使用C中的指针交换列

时间:2018-10-05 05:23:03

标签: c arrays pointers matrix

我真的对这个问题感到困惑,我的C代码在使用多维数组时效果很好,但是我需要使用指针来做同样的事情,但是我将首先描述问题。

具有以下矩阵,我将得到一个数字,该数字将是排列的数量(将向右移动的列交换数,而最后一列将移动到第一列)。

例如

列的排列数:5

| 1 2 3 | -----> | 2 3 1 |

| 3 1 2 | -----> | 1 2 3 |

| 2 3 1 | -----> | 3 1 2 |

我用指针编写了以下代码,如您所见,我用多维数组构建矩阵并将其全部分配给指针:

short elementMatrix[3][3] = {{1, 2, 3},
                             {3, 1, 2},
                             {2, 3, 1}};
short *element_matrix;
element_matrix = *elementMatrix;

int counter = 1;
while (counter <= 5)
{
       for (int i = 0; i < 3; i++)
       {
            int temp = elementMatrix[i][PR.elem_mat_size - 1];
            *outElementMatrix = *outElementMatrix + i * PR.elem_mat_size + PR.elem_mat_size - 1;

            for (int j = 3 - 1; j >= 0; j--)
            {
               *(outElementMatrix + i * PR.elem_mat_size + j) = *(outElementMatrix + i * PR.elem_mat_size + j - 1);

                if (j == 0)
                {
                   *(outElementMatrix + i * PR.elem_mat_size + j) = *outElementMatrix;
                }
            }       
        }
   counter++;                                    
}

2 个答案:

答案 0 :(得分:1)

由于您要换出列,因此使指针代表列是有意义的。这样,您可以交换指针来交换列。因此,让我们有3个指向一列的指针的数组。

short* col[3];

每列包含3个short,因此请分配那么多的内存。

for (int i = 0; i < 3; i++) {
    col[i] = (short*)malloc(3 * sizeof(short));
}

现在初始化矩阵。这有点冗长,因此,如果有人知道更好的方法,请删除。 :)

col[0][0] = 1;  col[1][0] = 2;  col[2][0] = 3;
col[0][1] = 3;  col[1][1] = 1;  col[2][1] = 2;
col[0][2] = 2;  col[1][2] = 3;  col[2][2] = 1;

现在我们进行交换。请注意您如何需要一个临时变量,如Rishikesh Raje建议的那样。还要注意,三个交换使它恢复到原始状态,因此不必交换n次,而只需交换n % 3次。当然,如果进行5或2次互换,它将立即生效,但是如果您必须进行10亿次互换,那么两者之间的差异应该是显而易见的。

for (int i = 0; i < 5; i++) {
    short* temp = col[2];
    col[2] = col[1];
    col[1] = col[0];
    col[0] = temp;
}

我们通过打印来确保结果是正确的

for (int i = 0; i < 3; i++) {
    printf("%d %d %d\n", col[0][i], col[1][i], col[2][i]);
}

答案 1 :(得分:0)

您可以将置换视为矩阵中每一行的旋转,除非必须在每个步骤之后以某种方式使用矩阵,否则仅计算最终结果。

我将使用一个额外的缓冲区来帮助进行交换。

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

// rotate the values of an array using a buffer to ease the swappings
void rotate_(size_t n, void *arr, void *tmp, size_t offset)
{
    assert(n  &&  arr  &&  tmp  &&  offset <= n);
    // casting to perform pointer arithmetic
    memcpy(tmp, (char *)arr + (n - offset), offset);
    memmove((char *)arr + offset, arr, n - offset);
    memcpy(arr, tmp, offset);
}

void rotate_columns_short(size_t r, size_t c, short mat[r][c], short *buf, int n)
{
    // clamp the value of the offset to the number of columns
    size_t offset = (n >= 0
                    ? n % c
                    : c - -n % c) * sizeof(short);

    // transform each row
    for (short *row = &mat[0][0], *row_end = row + r * c;
         row != row_end;
         row += c)
    {
        rotate_(c * sizeof(short), row, buf, offset);
    }
}

void print_matrix_short(size_t r, size_t c, short mat[r][c])
{
    for (size_t i = 0; i < r; ++i)
    {
        for (size_t j = 0; j < c; ++j)
        {
            printf(" %hd", mat[i][j]);
        }
        puts("");
    }
}

#define ROWS 3
#define COLS 3

int main(void)
{
    short matrix[ROWS][COLS] = {{1, 2, 3},
                                {3, 1, 2},
                                {2, 3, 1}};
    short buf[COLS];

    print_matrix_short(ROWS, COLS, matrix);
    puts("");

    rotate_columns_short(ROWS, COLS, matrix, buf, 5);

    print_matrix_short(ROWS, COLS, matrix);

}

输出蜂:

 1 2 3
 3 1 2
 2 3 1

 2 3 1
 1 2 3
 3 1 2