在 C 中交换一维数组的 Columns/Rows

Swapping Columns/Rows of 1-Dimensional Arrays in C

尝试在一维数组中创建两个矩阵函数(一个用于交换列,一个用于交换行)。显然,它们在结构上是相似的。

void col_swap(int a[], int col1, int col2, int colSize, int rowSize) {
  int d[size];
  int space = col2 - col1;
  for (int i = 0; i < rowSize; i++) {
    for (int j = 0; j < colSize; j++) {
      if (i == (col1 - 1) || i == (j * (col1-1))) {
        d[i+space] = a[i];
      } else if (i == (col2 - 1) || i == (j * (col2-1))) {
        d[i-space] = a[i];
      } else {
        d[i] = a[i];
      }
    }
    printf("%d  ", d[i]);
      if ((i+1) % colSize == 0) {
          printf("\n");
      }
  }
}

是的,矩阵必须是一维数组。这也不能完全起作用。

编辑:COL1COL2 分别不是 "the first column of matrix" 和 "the second column of matrix"。它们是我们要切换的矩阵的任意两列。

void row_swap(int a[], int row1, int row2, int rowSize, int colSize) {
  for (int i = 0; i < colSize; i++) {
    int temp = a[i*rowSize+row1];
    a[i*rowSize+row1] = a[i*rowSize+row2];
    a[i*rowSize+row2] = temp;
  }
  for (int i = 0; i < size; i++) {
    if (i % colSize == 0) {
      printf("\n");
    }
    printf("%d ", a[i]);
  }
}

我有上面的 row_swap 函数,但是当我给它一个矩阵时

1, 4,
2, 3,
3, 2,
4, 1

它returns

1, 3
2, 4
3, 1
4, 2

这比您想象的要容易得多。

所以你想交换 col1col2,这里矩阵有 rowsize 行数和 colsize 列数。

void col_swap(int a[], int col1, int col2, int colSize, int rowSize) {
  for(int i=0;i<rowSize;i++){
    int t=a[i*colSize+col1];
    a[i*colSize+col1]=a[i*colSize+col2];
    a[i*colSize+col2]=t; 
  }
}

想想这里有什么不同。我们刚刚计算清楚了位置的逻辑。然后一切都与标准交换相同。

在结构上你可以这样做:-

void swap(int *a,int*b)
{
    int t=*a;
    *a=*b;
    *b=t;
}
void col_swap(int a[], int col1, int col2, int colSize, int rowSize) {
  for(int i=0;i<rowSize;i++){
    swap(&a[i*colSize+col1],&a[i*colSize+col2]); 
  }
}

行交换是相同的。如果您将行视为列,反之亦然,这类似于列交换。

其次,为什么要通过在一维数组中使用二维数组来使事情复杂化?

这很难在生产级代码或更具体的软件中使用。为什么不使用二维数组本身?你应该使用它而不是这样做。


方法是什么?

看完问题后,我只是用纸来了解我想做什么以及它如何从二维数组映射到一维数组。这有助于很多时间。然后首先编写第一个解决方案。我可以看到我也可以在行交换的情况下重用交换部分。所以我把它拿出来放在不同的函数中 swap.

示例输入输出示例:

int a[]={1,2,3,4,5,6,7,8,9,10,11,12};
    col_swap(a,1,2,3,4);

// 1 2 3 
// 4 5 6 
// 7 8 9 
// 10 11 12

// 1 3 2 
// 4 6 5 
// 7 9 8 
// 10 12 11

再考虑一下:

col_swap(a,0,2,3,4); 在同一个数组上导致

// 3 2 1
// 6 5 4
// 9 8 7
// 12 11 10

我在代码中使用了 0 索引。所以当你给输入列时要小心。

另外一个函数是:-

void row_swap(int a[], int row1, int row2, int colSize, int rowSize) {
  for(int i=0;i<colSize;i++){
    swap(&a[colSize*row1+i],&a[row2*colSize+i]); 
  }
}

如果您使用的是 C99,那么指向 Variable Length Arrays 的指针可以使索引更容易:

void col_swap(int a[], int col1, int col2, int colSize, int rowSize)
{
    // Cast 'a' to a pointer to a variable length array of size 'colSize'
    int (*a2d_matrix)[colSize] = (int (*)[colSize])a;

    // Now we can index into a (through a2d_matrix) as if it really is
    // a 2 dimensional matrix
    for(int r = 0; r < rowSize; r++)
    {
        int temp = a2d_matrix[r][col1];
        a2d_matrix[r][col1] = a2d_matrix[r][col2];
        a2d_matrix[r][col2] = temp; 
    }
}

我经常使用这种方法。请注意,此 可能 适用于 C11 及更高版本,但是可变长度数组在 C11 标准中是可选的。因此,请检查您的编译器是否支持可选的 C11 功能。据我所知,所有主要供应商都支持 C11 中的 VLA。