如何重新排列二维数组

时间:2017-06-03 22:23:26

标签: c

我想将一个数组中的值分配给另一个数组,但是在另一个数组中 订购。例如,原始数组将是:

1  2  3  4  5  6  7  
8  9  10 11 12 13 14 
15 16 17 18 19 20 21

所需的数组是:

8  11 14 3 6  16 19
9  12 1  4 7  17 20 
10 13 2  5 15 18 21

我该怎么做?在下面的代码中,我将选定的行移动到中心,然后分别为每个数组分配。我无法找到更好的方法。

int main()
{
int decide, i, j, k;
int save[3][7];
int shuffle[3][7];
int arr[3][7] = {
                {1, 2, 3, 4, 5, 6, 7},
                {8, 9, 10, 11, 12, 13, 14}, 
                {15, 16, 17, 18, 19, 20, 21}
            };

printf("Select a number between 1 and 21\n\n0-GroupA (1 - 7))\n1-GroupB ( 8 - 14)\n2-GroupC (15 - 21)\n\n");

for(k = 0 ; k < 1 ; ++k)
{
    printf("Select which group the number falls into:");
    scanf("%d", &decide);

    for(j = 0 ; j < 7 ; ++j)
    {/*moves selected row to middle row of array*/
        save[0][j] = arr[1][j]; 
        arr[1][j] = arr[decide][j];
        arr[decide][j] = save[0][j];
    }

    /*this is a horrible method*/
    shuffle[0][0] = arr[0][0];
    shuffle[1][0] = arr[0][1];
    shuffle[2][0] = arr[0][2];
    shuffle[0][1] = arr[0][3];
    shuffle[1][1] = arr[0][4];
    shuffle[2][1] = arr[0][5];
    shuffle[0][2] = arr[0][6];
    shuffle[1][2] = arr[1][0];
    shuffle[2][2] = arr[1][1];
    shuffle[0][3] = arr[1][2];
    shuffle[1][3] = arr[1][3];
    shuffle[2][3] = arr[1][4];
    shuffle[0][4] = arr[1][5];
    shuffle[1][4] = arr[1][6];
    shuffle[2][4] = arr[2][0];
    shuffle[0][5] = arr[2][1];
    shuffle[1][5] = arr[2][2];
    shuffle[2][5] = arr[2][3];
    shuffle[0][6] = arr[2][4];
    shuffle[1][6] = arr[2][5];
    shuffle[2][6] = arr[2][6];

}

3 个答案:

答案 0 :(得分:0)

您无法转置矩阵。也就是说,不可能编写一个函数来获取矩阵并对其进行修改以使其成为转置函数,而无需创建相同大小的临时矩阵。至少没有一些非常奇特的编程。

现在你的任务不完全是转置,但似乎非常相似。所以我不希望有一个很好的,到位的解决方案。您必须简单地创建一个临时表,将映射从输入应用到临时,然后重新写入值。

这可能会有所帮助。

/* swap two rows of a matrix */
void swaprows(int *mtx, int width, int height, int rowa, int rowb)
{
   int i;

   for(i=0;i<width;i++)
   {
      int temp = mtx[rowa*width+i];
      mtx[rowa*width+i] = mtx[rowb*width+i];
      mtx[rowa*width+i] = temp;
   }
} 

/* transpose a matrix */
int transpose(int *mtx, int width, int height)
{
    int *tmtx = malloc(width*height*sizeof(int));
    if(!tmtx)
       return -1;
    for(y=0;y<width;y++)
      for(x=0;x<height;x++)
        tmtx[y*height+x] = mtx[x*width+y];

    mempy(mtx, tmtx, width * height * sizeof(int));
    free(tmtx);
}


/* your logic  */

int arr[3][7] = {
            {1, 2, 3, 4, 5, 6, 7},
            {8, 9, 10, 11, 12, 13, 14}, 
            {15, 16, 17, 18, 19, 20, 21}
        };

 swaprows((int *) arr, 7, 3, 0, 1);
 transpose(int *) arr, 7, 3);

这似乎是你想要做的。

答案 1 :(得分:0)

像这样?

#include <stdio.h>

#define ROWS 3
#define COLS 7

int main(void){
    int arr[ROWS][COLS] = {
        {1, 2, 3, 4, 5, 6, 7},
        {8, 9, 10, 11, 12, 13, 14}, 
        {15, 16, 17, 18, 19, 20, 21}
    };
    int result[ROWS][COLS];
    int order[ROWS] = {1, 0, 2};
    int n = sizeof(arr)/sizeof(**arr);//number of elements
    int r = 0, c = 0, i = 0, j = 0;

    while(n--){
        result[r++][c] = arr[order[i]][j++];
        if(r == ROWS){
            r = 0;
            c += 1;
        }
        if(j == COLS){
            j = 0;
            i += 1;
        }
    }
    //check print
    for(r = 0; r < ROWS; ++r){
        for(c = 0; c < COLS; ++c)
            printf("%-2d ", result[r][c]);
        puts("");
    }
}

答案 2 :(得分:0)

换位部分可以这样做:

#include <stdio.h>

typedef struct Sequence2D
{
    int idx_slow;
    int idx_fast;
    int max_slow;
    int max_fast;
} Sequence2D;

static inline void next2D(Sequence2D *seq)
{
    if (++seq->idx_fast == seq->max_fast)
    {
        seq->idx_fast = 0;
        if (++seq->idx_slow == seq->max_slow)
            seq->idx_slow = 0;
    }
}

static inline void dump2D(const char *tag, int rows, int cols, int data[rows][cols])
{
    printf("%s:\n", tag);
    for (int r = 0; r < rows; r++)
    {
        for (int c = 0; c < cols; c++)
            printf("%3d", data[r][c]);
        putchar('\n');
    }
}

enum { ROWS = 3, COLS = 7 };

int main(void)
{
    int src[ROWS][COLS] =
    {
        {  1,  2,  3,  4,  5,  6,  7 },
        {  8,  9, 10, 11, 12, 13, 14 },
        { 15, 16, 17, 18, 19, 20, 21 },
    };
    int dst[ROWS][COLS];
    Sequence2D dst2D = { 0, 0, COLS, ROWS };
    Sequence2D src2D = { 0, 0, ROWS, COLS };

    dump2D("Source", ROWS, COLS, src);

    for (int i = 0; i < ROWS * COLS; i++)
    {
        dst[dst2D.idx_fast][dst2D.idx_slow] = src[src2D.idx_slow][src2D.idx_fast];
        printf("dst[%d][%d] = src[%d][%d] = %d\n",
               dst2D.idx_fast, dst2D.idx_slow,
               src2D.idx_slow, src2D.idx_fast,
               dst[dst2D.idx_fast][dst2D.idx_slow]);
        next2D(&dst2D);
        next2D(&src2D);
    }

    dump2D("Target", ROWS, COLS, dst);

    return 0;
}

Sequence2D结构加上next2D()函数循环通过数组索引,在每次调用next2D()时更改快速索引,在必要时更改慢速索引。这样可以节省您编写21个分配的顺序,并立即缩放到其他形状,而无需您做太多额外的工作。实际上,将所有大小作为运行时输入而不是编译时常量来处理并不需要太多。

此代码的输出为:

Source:
  1  2  3  4  5  6  7
  8  9 10 11 12 13 14
 15 16 17 18 19 20 21
dst[0][0] = src[0][0] = 1
dst[1][0] = src[0][1] = 2
dst[2][0] = src[0][2] = 3
dst[0][1] = src[0][3] = 4
dst[1][1] = src[0][4] = 5
dst[2][1] = src[0][5] = 6
dst[0][2] = src[0][6] = 7
dst[1][2] = src[1][0] = 8
dst[2][2] = src[1][1] = 9
dst[0][3] = src[1][2] = 10
dst[1][3] = src[1][3] = 11
dst[2][3] = src[1][4] = 12
dst[0][4] = src[1][5] = 13
dst[1][4] = src[1][6] = 14
dst[2][4] = src[2][0] = 15
dst[0][5] = src[2][1] = 16
dst[1][5] = src[2][2] = 17
dst[2][5] = src[2][3] = 18
dst[0][6] = src[2][4] = 19
dst[1][6] = src[2][5] = 20
dst[2][6] = src[2][6] = 21
Target:
  1  4  7 10 13 16 19
  2  5  8 11 14 17 20
  3  6  9 12 15 18 21

如果您在复制“转置”之前根据您使用的任何晦涩规则重新排列初始矩阵(src)。将src放入结果(dst)中,那么你应该能够得到你想要的结果。

如上所述,使用C99和可变长度数组可以很容易地推广代码:

#include <assert.h>
#include <stdio.h>

typedef struct Sequence2D
{
    int idx_slow;
    int idx_fast;
    int max_slow;
    int max_fast;
} Sequence2D;

static inline void next2D(Sequence2D *seq)
{
    if (++seq->idx_fast == seq->max_fast)
    {
        seq->idx_fast = 0;
        if (++seq->idx_slow == seq->max_slow)
            seq->idx_slow = 0;
    }
}

static inline void dump2D(const char *tag, int rows, int cols, int data[rows][cols])
{
    printf("%s:\n", tag);
    for (int r = 0; r < rows; r++)
    {
        for (int c = 0; c < cols; c++)
            printf("%3d", data[r][c]);
        putchar('\n');
    }
}

static void transpose(int rows, int cols)
{
    assert(rows * cols < 1000000);
    int src[rows][cols];
    int dst[rows][cols];
    Sequence2D dst2D = { 0, 0, cols, rows };
    Sequence2D src2D = { 0, 0, rows, cols };
    int cells = rows * cols;
    for (int i = 0; i < cells; i++)
    {
        src[src2D.idx_slow][src2D.idx_fast] = i;
        next2D(&src2D);
    }
    /* src2D is back to its initial state! */

    dump2D("Source", rows, cols, src);

    for (int i = 0; i < cells; i++)
    {
        dst[dst2D.idx_fast][dst2D.idx_slow] = src[src2D.idx_slow][src2D.idx_fast];
        printf("dst[%d][%d] = src[%d][%d] = %d\n",
               dst2D.idx_fast, dst2D.idx_slow,
               src2D.idx_slow, src2D.idx_fast,
               dst[dst2D.idx_fast][dst2D.idx_slow]);
        next2D(&dst2D);
        next2D(&src2D);
    }

    dump2D("Target", rows, cols, dst);
}

int main(void)
{
    transpose(3, 7);
    transpose(9, 4);
    return 0;
}

输出的第一部分与之前相同; 9x4部分看起来像:

Source:
  0  1  2  3
  4  5  6  7
  8  9 10 11
 12 13 14 15
 16 17 18 19
 20 21 22 23
 24 25 26 27
 28 29 30 31
 32 33 34 35
dst[0][0] = src[0][0] = 0
dst[1][0] = src[0][1] = 1
dst[2][0] = src[0][2] = 2
dst[3][0] = src[0][3] = 3
dst[4][0] = src[1][0] = 4
dst[5][0] = src[1][1] = 5
dst[6][0] = src[1][2] = 6
dst[7][0] = src[1][3] = 7
dst[8][0] = src[2][0] = 8
dst[0][1] = src[2][1] = 9
dst[1][1] = src[2][2] = 10
dst[2][1] = src[2][3] = 11
dst[3][1] = src[3][0] = 12
dst[4][1] = src[3][1] = 13
dst[5][1] = src[3][2] = 14
dst[6][1] = src[3][3] = 15
dst[7][1] = src[4][0] = 16
dst[8][1] = src[4][1] = 17
dst[0][2] = src[4][2] = 18
dst[1][2] = src[4][3] = 19
dst[2][2] = src[5][0] = 20
dst[3][2] = src[5][1] = 21
dst[4][2] = src[5][2] = 22
dst[5][2] = src[5][3] = 23
dst[6][2] = src[6][0] = 24
dst[7][2] = src[6][1] = 25
dst[8][2] = src[6][2] = 26
dst[0][3] = src[6][3] = 27
dst[1][3] = src[7][0] = 28
dst[2][3] = src[7][1] = 29
dst[3][3] = src[7][2] = 30
dst[4][3] = src[7][3] = 31
dst[5][3] = src[8][0] = 32
dst[6][3] = src[8][1] = 33
dst[7][3] = src[8][2] = 34
dst[8][3] = src[8][3] = 35
Target:
  0  9 18 27
  1 10 19 28
  2 11 20 29
  3 12 21 30
  4 13 22 31
  5 14 23 32
  6 15 24 33
  7 16 25 34
  8 17 26 35