2

質問をより明確にするために、疑似コードを記述します。このコードは C で作成されることに注意してください。

任意の数の配列があるとします。最初の数字は、扱っている配列の大きさを示しています。たとえば、最初の数値が 3 の場合、2 つの 3x3 マトリックスがあることを意味します。そこで、次のように 2 つの多次元配列を作成します。

matrix1[3][3]
matrix2[3][3]

私が苦労しているのは、すべての数値を行列に割り当てるための算術/コーディングです。それがどのように行われるかを視覚化するのに非常に苦労しています。

テスト配列に [2,1,2,3,4,5,6,7,8] が含まれていると想像してください

私のプログラムには、次の2つのマトリックスが必要です。

1 2    5 6
3 4    7 8

複数のネストされたループが必要ですか? どんな助けでも大歓迎です。

4

5 に答える 5

1

現時点で唯一のアイデアは two を使用することですfor loopskまたは、関数を作成して、必要なときに呼び出すこともできます (ただし、2 番目の引数として使用することを忘れないでください)。

int i, j, k;

/* We start in the 2nd element of the array that's why k = 1. */
k = 1;

/* Now we fill the array1 copying 1 by 1 the elements of the "test array" until
   we fill it. Then we do the same with the array2. */
for( i = 0; i < test[ 0 ]; i++ ){
   for( j = 0; j < test[ 0 ]; j++ ){
       array1[ i ][ j ] = test[ k ]
       k++;
   }
}

for( i = 0; i < test[ 0 ]; i++ ){
   for( j = 0; j < test[ 0 ]; j++ ){
       array2[ i ][ j ] = test[ k ]
       k++;
   }
}
于 2012-11-20T02:13:22.540 に答える
1

データは行優先順に表示されます。整数配列を読み取って内容を検証した後 (つまり、dim=4 は 32 個の値が続くことを意味し、dim=2 は 8 個の値が続くことを意味します)、何かを割り当てたりループしたりする理由がわかりません。

つまり、物理的なtest [] データをマトリックスとして使用できます

int dim = test[0];
int (*mat1)[dim] = (int (*)[dim])(test+1);
int (*mat2)[dim] = (int (*)[dim])(test+1 + dim*dim);

C99 は、実装レベルで変数配列宣言をサポートします (つまり、コンパイラは、標準で定義されている機能をサポートできますが、必須ではありません詳細については、C99 標準の 6.7.6.2 を参照してください)。ツールチェーンがサポートしていない場合は、定義済みのマクロを定義する必要があり、コンパイル時にテストできます (C99 標準のセクション 6.10.8.3-1 を参照)。そうは言っても、私が過去 10 年以上使用してきたすべての C99 準拠のコンパイラはそれをサポートしてます。__STDC_NO_VLA__

そうである場合、mat1上記の宣言での「dim」の使用に注意してくださいmat2)。これは、C++ にはない CI の数少ない機能の 1 つです。だからあなたが持ってきたものと一緒に踊ってください。

最後に、コンパイラが C99 に準拠し、VLA をサポートしている (__STDC_NO_VLA__定義されていない) と仮定すると、追加の超特別ボーナスとして、アルゴリズムがないため、2 つの行列を取得する最速のアルゴリズムであることがほぼ保証されます。1 つの配列要素を読み取ってから、2 つのポインターを割り当てます。O(3) に勝るものはありません。

#include <stdlib.h>
#include <stdio.h>

// main loader.
int main(int argc, char *argv[])
{
    int test[] = {2,1,2,3,4,5,6,7,8};
    int dim = test[0];
    int (*mat1)[dim] = (int (*)[dim])(test+1);
    int (*mat2)[dim] = (int (*)[dim])(test+1 + dim*dim);

    // proof stuff is where it should be.
    int i=0,j=0;
    for (i=0;i<dim;i++)
    {
        for (j=0;j<dim;printf("%d ", mat1[i][j++]));
        printf ("   ");
        for (j=0;j<dim;printf("%d ", mat2[i][j++]));
        printf("\n");
    }

    return EXIT_SUCCESS;
}

出力

1 2    5 6 
3 4    7 8 

3x3 データ セットを使用した同様のテスト:

int test[] = {3,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1};

出力

1 2 3    9 8 7 
4 5 6    6 5 4 
7 8 9    3 2 1 

最後に、4x4 データセット:

int test[] = {4,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,8,7,6,5,4,3,2,1,8,7,6,5,4,3,2,1};

出力

1 2 3 4    8 7 6 5 
5 6 7 8    4 3 2 1 
1 2 3 4    8 7 6 5 
5 6 7 8    4 3 2 1 
于 2012-11-20T03:20:05.380 に答える
0

2D配列は、マトリックスからの連続した一連の行に格納されます。したがって、元のアレイを使用できる新しいメモリを割り当てる必要もありません。とにかく、2つの新しいスタンドアロンアレイを作成することもできます。このような関数を作成して、正しい数の行列を取得できます。

int getNumber(int array[], int arraynumber, int index_x, int index_y)
{
   return array[(((array[0]*index_x)+index_y)+1)+((array[0]*array[0])*arraynumber)];
}

arraynumber変数は、最初の行列の場合は0、2番目の行列の場合は1です。この機能は、すべてのパラメーターが正しい場合にのみ機能するため、エラー検出は行われません。
この関数を使用すると、簡単にループして2つの新しい配列を作成できます。

int i,k;
for (i=0; i<array[0]; i++)
{
   for (k=0; k<array[0]; k++)
   {
      newarray1[i][k] = getNumber(array, 0, i,k);
      newarray2[i][k] = getNumber(array, 1, i,k);
   }
}
于 2012-11-20T02:29:58.433 に答える
0

これは、単一のループで機能するものです。ネストもリピートもありません。他の回答よりも優れているかどうかはわかりませんが、別の回答をしたいと思いました^_^

私はこのコードをテストしていませんが、アルゴリズムのロジックが機能しているように見えます - それがポイントですよね? エラーがあれば教えてください。...

int c=0, x=0, y=0, size=test[0], length=sizeof(test);

for(i=1; i<length; i++) {
    if((c-size)<0) {
        matrix1[x][y] = test[i];
    } else {
        matrix2[x][y] = test[i];
    }
    ++y;
    if(y%size == 0) {
        ++c;
        y = 0;
        x = (c-size)<0 ? ++x : 0;
    }
}
于 2012-11-20T02:32:09.703 に答える
0

C の多次元配列の問題は、事前に (コンパイル時に) 次元サイズの n-1 を知る必要があることです。関数パラメーターとして使用すると、それらもドラッグになります。

いくつかの代替アプローチがあります。

  1. 配列の配列を作成します。つまり、配列ポインターの配列を割り当ててから、それらのポインターに配列を割り当てます。

    type **array = malloc(sizeof(type * ) * < firstnumread > );
    array[0] = malloc(sizeof(type) * < firstnumread > );
    ...

  2. 乗算されたすべての次元のサイズを持つ 1 次元配列を割り当てます。すなわち

    type *array = malloc(sizeof(type) * < firstnumread > * < firstnumread >);

あなたの場合、おそらく2番目の方が適切です。何かのようなもの:

matrix1 = malloc(sizeof(type)*<firstnumread>*<firstnumread>);  
matrix2 = malloc(sizeof(type)*<firstnumread>*<firstnumread>);

次に、次のように値を割り当てることができます。

matrix1[column*<firstnumread> + row] = <value>;

はい、2forループで。

于 2012-11-20T02:19:16.983 に答える