【问题标题】:Multidimensional manipulation in C by Column在 C 中按列进行多维操作
【发布时间】:2018-03-14 23:34:08
【问题描述】:

这个功能仍然没有很好的定义,我可以在堆栈溢出的任何地方找到。

与向上移动整列或整行相关的代码或定理是什么?比如

1 2 3
4 5 6
7 8 9

如果我把最后一列往上推,那就是

1 2 6
4 5 9
7 8 3

如果我将最后一行向右推,那将是

1 2 6
4 5 9
3 7 8

我想知道解决这类问题的所有不同类型的方法。

我知道的一种方法是找到一个数组,由于多维数组只是数组的数组,我可以将该数组收集到一个新数组中吗?指针?解释。这是一个很难掌握的概念。

【问题讨论】:

  • 你能想到如何旋转一维数组吗?喜欢[1,2,3] 变成[3,1,2]
  • 把数组看成一个环怎么样?其中每个实体都被链接,然后最后一个链接回第一个。 :P
  • 什么@EugeneSh。说 - 把问题分开。首先旋转一维数组,将最后一个值复制到一些“溢出”临时变量中,向上复制值,将溢出放回最低位置。一旦工作正常,您可以在另一个维度中进行编辑。复杂的问题?把它分开:)
  • 想想戒指。 7 天。
  • 请注意,您的左移示例是错误的。

标签: c arrays algorithm pointers multidimensional-array


【解决方案1】:

有很多方法可以解决这个问题。

让我们从简单的开始。在这里,我们不移动东西,而只是让它看起来像它。所以对于一个 n 元素数组:

An = [ e0, e1, e2, ..., en-1 ];

我们可以对索引进行有趣的数学运算(使用它的大小和余数函数),以从第 ith 元素开始旋转数组,其中 0 ≤ k 。制作的伪代码是:

    i = (n - (k - j)) % n

让我们看一个旋转整数数组的示例程序,它从命令行获取一个起点,并列出数组中的元素,就好像起点是 0 一样,终点连接回开始。

rotate1.c:

#include <stdio.h>
#include <stdlib.h>

const int a[] = { 10, 20, 30, 40, 50 };
const int N = sizeof(a) / sizeof(int);

int main(int argc, char *argv[]) {
    int i, j;
    int BASE = 0;
    if (argc > 1) {
        BASE = atoi(argv[1]);
    }
    for(j = 0; j < N; j++) {
        i = (N - (BASE - j)) % N;
        fprintf(stderr, "%d\n", a[i]);
    }
}

您可以修改此程序以旋转任何类型的数组,甚至是矩阵的列或行,因为它们只是数组的数组。

另一种方法是使用戒指。

使用链表创建环

作为链表的环,链表的最后一个元素指向链表的第一个元素。

Linux 内核 list.h 实现了双重链接的“环”。有一个戒指有很好的后果。例如,由于没有实际的头部,所以每个元素都作为头部工作;如果你有一个双重链接的“环”,你可以简化编程。

我不会详细介绍它是如何实现的,因为规范的实现可以在include/linux/list.h 的 linux 内核源代码中找到,并且文档非常精美。

【讨论】:

【解决方案2】:

要旋转一列或一行,您可以先将一个元素复制到一个临时变量。然后用另一个元素覆盖该元素。然后用第三个元素覆盖第二个元素,依此类推,直到到达列/行的末尾。然后用 temp 变量覆盖最后一个元素。

可以像这样显示向上旋转一列。红色数字是要执行的步骤。

这里有一些代码可以帮助你入门。

#include <stdio.h>

// column  : The column to rotate
// rows    : The total number of rows
// columns : The total number of columns
void rotate_column_up(int column, int rows, int columns, int arr[][columns])
{
    int i;
    int temp = arr[0][column];
    for (i=1; i<rows; ++i)
    {
        arr[i-1][column] = arr[i][column];
    }
    arr[rows-1][column] = temp;
}

void rotate_column_down(int column, int rows, int columns, int arr[][columns])
{
    int i;
    int temp = arr[rows-1][column];
    for (i=rows-1; i>0; --i)
    {
        arr[i][column] = arr[i-1][column];
    }
    arr[0][column] = temp;
}

// row     : The row to rotate
// rows    : The total number of rows
// columns : The total number of columns
void rotate_row_left(int row, int rows, int columns, int arr[][columns])
{
    int i;
    int temp = arr[row][0];
    for (i=1; i<columns; ++i)
    {
         arr[row][i-1] = arr[row][i];
    }
    arr[row][columns-1] = temp;
}

void rotate_row_rigth(int row, int rows, int columns, int arr[][columns])
{
    int i;
    int temp = arr[row][columns-1];
    for (i=columns-1; i>0; --i)
    {
         arr[row][i] = arr[row][i-1];
    }
    arr[row][0] = temp;
}

void print_array(int columns, int rows, int arr[][columns])
{
    int i, j;
    for(j=0; j<rows; ++j)
    {
        for(i=0; i<columns; ++i)
        {
            printf("%d ", arr[j][i]);
        }
        printf("\n");
    }
        printf("\n");
}

int main(void) {
    int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    printf("Original array\n");
    print_array(3, 3, arr);

    printf("Column 2 up\n");
    rotate_column_up(2, 3, 3, arr);
    print_array(3, 3, arr);

    printf("Row 2 rigth\n");
    rotate_row_rigth(2, 3, 3, arr);
    print_array(3, 3, arr);

    printf("Row 2 left\n");
    rotate_row_left(2, 3, 3, arr);
    print_array(3, 3, arr);

    printf("Column 2 down\n");
    rotate_column_down(2, 3, 3, arr);
    print_array(3, 3, arr);

    return 0;
}

输出:

Original array
1 2 3
4 5 6
7 8 9

Column 2 up
1 2 6
4 5 9
7 8 3

Row 2 rigth
1 2 6
4 5 9
3 7 8

Row 2 left
1 2 6
4 5 9
7 8 3

Column 2 down
1 2 3
4 5 6
7 8 9

【讨论】:

  • 您的代码无法编译。这个 c=99 兼容吗?
  • @compute 我发布的第一个代码并不完全正确,因此我将其更新为更简单的版本。感谢您指出第一个版本存在一些问题。
猜你喜欢
  • 2015-06-28
  • 2020-04-01
  • 1970-01-01
  • 2017-06-15
  • 2015-02-14
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多