4

与えられた:

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

チャンクサイズ CS を指定して、2 次元配列 (struct MATRIX) を struct MATRIX の配列に分割したい: cs が 2 であると仮定すると、答えは次のようになります。

Seg[0]:
1 2 
1 2 
1 2
Seg[1]:
3 4 
3 4 
3 4
....
Seg[3]:
7 8
7 8
7 8

ここに私の行列構造があります:

typedef struct MATRIX {
    int nrow;
    int ncol;
    int **element;
} MATRIX;

そして、これらを分離する関数は次のとおりです。

void SegmentMatrix(MATRIX input,MATRIX* segs,int Chunksize, int p) {
    int i,j,r;

    //Allocate segs
    for (i = 0; i<p;i++)
    {
        CreateMatrix(&(segs[i]),input.nrow ,Chunksize,0);
    }

    //Now Copy the elements from input to the segs
    //where seg0 takes from 0 to cs cols of a, and all their rows, and seg1 takes from cs to 2cs ...
    printf("Stats:\n\t P: %d\t CS: %d\n",p,Chunksize);
    for (r = 0; r<p; r++) {
        for (i = 0; i<input.nrow;i++) {
            for (j = r*Chunksize; j<r*Chunksize+Chunksize-1; j++) {
                 //I tried (&(segs[r]))->element... Doesn't work, produces wrong data
                 segs[r].element[i][j] = input.element[i][j];

        }
    }
    PRINTM(segs[r]);
    }


}

PRINTM は基本的に行列を出力し、segs[r].nrow と ncol をチェックして制限を認識し、CreateMatrix は次の入力 (&matrix、行数、列数、filltype) と malloc を内部から取得することに注意してください。

filltype: 
0- generates zeroth matrix
1- generates identity
else A[i][j] = j; for simplicity

問題は、マトリックス Segs[i] を出力すると、新しく追加された値ではなく、CreateMatrix によって指定されたデフォルト値がすべて出力されることです。

明確化: わかりました。SegmentMatrix 関数の最後の PRINTM をチェックすると、for ループが発生しなかったかのように行列が出力されます。別名、for ループを削除しても同じ出力が得られます。この行が間違っています (SegmentMatrix から取得)

Segs[r].element[i][j] = input.element[i][j];
4

2 に答える 2

5

ChunkSizeandによる乗算で操作している理由と内容がわかりませんr(とにかく初期化されていません)。コードを単純化することをお勧めします (経験則: 乱雑に見える場合は、複雑すぎます)。必要なのは、チャンクの配列を格納するための 3 次元配列と、適切なチャンクの適切な列に挿入するためのモジュロ演算と整数除算だけです。

/* the variable-sized dimension of the `chunks' argument is w / chsz elements big
 * (it's the number of chunks)
 */
void split(int h, int w, int mat[h][w], int chsz, int chunks[][h][chsz])
{
    /* go through each row */
    for (int i = 0; i < h; i++) {
        /* and in each row, go through each column */
        for (int j = 0; j < w; j++) {
            /* and for each column, find which chunk it goes in
             * (that's j / chsz), and put it into the proper row
             * (which is j % chsz)
             */
            chunks[j / chsz][i][j % chsz] = mat[i][j];
        }
    }
}

デモンストレーション、別名それを呼び出す方法:

int main(int agrc, char *argv[])
{
    const size_t w = 8;
    const size_t h = 3;
    const size_t c = 2;

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

    int chunks[w / c][h][c];

    split(h, w, mat, c, chunks);

    for (int i = 0; i < w / c; i++) {
        for (int j = 0; j < h; j++) {
            for (int k = 0; k < c; k++) {
                printf("%3d ", chunks[i][j][k]);
            }
            printf("\n");
        }
        printf("\n\n");
    }

    return 0;
}
于 2013-05-13T19:14:45.443 に答える
2

質問が不明確でした。だから私は彼がこれを達成する方法を知りたいだけだと思った. だから私はこの単純な疑似コードを書きました。それ以外の場合は、私の謝罪を受け入れてください:

matrix[i] matrix
//matrixes total column size should be bigger big 2d array column size
first condition check: sum(matrix[i].colsize)>=big2d.colsize
//in this simple code raw sizes must be equal
second condition: for all i matrix[i].rawsize=big2d.rawsize
//if columns sizes will be equal the algorithm could be simplified , does not mean optimized
 //splitting big2d into matrixes
for (int br=0;br<big2d.rawsize;br++){
i=0;//store matrix index
int previndex=0;//store offset for next matrix
  for(int bc=0;bc<big2d.colsize;bc++){

      matrix[i].val[bc-previndex][br]=big2d.val[bc][br]; //assign (bc,br) 

      if(bc-previndex==matrix[i].colsize-1){
             i++; //move to next matrix;//if we not have next matrix then break;
            previndex=bc+1; 
          }
     /*if it be for equal chunks matrixes offset can be calculated this way too
         matrix[bc/chunk].val[bc%chunk][br]=big2d.val[bc][br];
      */
  }//loop columns
}//loop raws
于 2013-05-13T18:59:47.087 に答える