【问题标题】:Splitting a 2D array to an array of smaller 2D arrays in C在 C 中将 2D 数组拆分为较小的 2D 数组的数组
【发布时间】:2013-05-07 21:14:53
【问题描述】:

给定:

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

我想将二维数组(struct MATRIX)拆分成一个 struct MATRIX 数组 给定一个块大小的 CS: 假设 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、行数、列数、填充类型)和 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];

【问题讨论】:

  • 您会在哪里调用 PRINTM 以显示错误输入?我希望在您的上述代码中看到这一点,以确保它不是马类型问题之前的推车。
  • 如果您查看 SegmentMatrix 中的最后一条语句,您将看到 PRINTM,它显示了 segs 的默认值,就好像整个 for 循环没有发生一样
  • @MichaelDorgan 希望能解释一下

标签: c arrays matrix


【解决方案1】:

问题不清楚。所以我认为他只想知道如何实现这一目标。 所以我写了这个简单的伪代码。否则接受我的道歉:

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

【讨论】:

  • 请添加一些 cmets 来说明您的代码正在做什么。自己也不清楚……
【解决方案2】:

我不明白为什么以及你用 ChunkSizer 的乘法来操作(无论如何都未初始化),我建议简化代码(经验法则:如果它看起来很乱,那也是复杂的)。您只需要一个 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];
        }
    }
}

演示,a。 ķ。一种。如何称呼它:

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;
}

【讨论】:

  • +1 认为他应该接受你的回答。我太累了,无法检查他的代码。就这么简单写了我的伪代码
  • 谢谢你们......我会尽快查看并回复,但结构是用来计算矩阵的大小以防万一
  • 这是一个程序的一部分,它应该从文件中读取矩阵,并使用 MPI (MPICH2) 对它们进行操作。这部分(我发布的部分)是关于将它们相乘的。使用上面的结构,我已经很容易地完成了序列化。块大小实际上是我将从矩阵 A 发送到节点的列数,它是在进程 0 中计算的,它只是传递给函数(我不明白为什么你认为它是 uninit),而 P 是进程数。最后一个 for 循环是为了确保无论我有多少进程,我都可以正确地调用这个循环,@H2CO3
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-16
  • 2014-08-31
  • 1970-01-01
  • 2018-07-05
  • 2020-03-21
  • 2017-10-08
相关资源
最近更新 更多