2017-06-03 125 views
-2

我想将一个数组中的值分配给另一个,但按不同的 顺序。例如原数组将是:如何重新排列二维数组

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

} 
+0

为什么你想这样洗牌?你想达到什么目的? – dbush

+0

洗牌背后的逻辑并不直观。它应该如何工作? –

+0

你只是想随机重新分配它们吗? – Makogan

回答

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

这似乎是你想要做的。

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(""); 
    } 
} 
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 
+0

我不会称之为奥术。我设定了符号。 –

+0

它是/是无法解释的,虽然它可能对您很明显,因为您知道自己在做什么以及为什么要这样做,但对于我们这些没有您具体背景知识的人来说,这并不明显你正在努力去做。就我而言,这使得它很神秘,作为一个无知的旁观者,当专家尚未设法明确解释他们的行为时,他们试图帮助认知。 –