【问题标题】:How to rotate a section of a 1d array in C?如何在C中旋转一维数组的一部分?
【发布时间】:2017-07-13 13:16:22
【问题描述】:

我打印了一个 6x6 的一维数组,但想逆时针旋转左上角的 3x3 部分。有这个算法吗?将来我还想像右下角 3x3 部分或右上角 3x3 部分或左下角 3x3 部分一样旋转。

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

【问题讨论】:

  • 3x3 是一种特殊情况,因为中间条目不会移动。你能告诉我们在 4x4 的情况下会发生什么吗?
  • 如果它是左上角的3x3矩阵,你能做到吗?如果不是,那可能是一个很好的第一步,学习如何做到这一点的最好方法就是在纸上做。当你让它在论文上工作时,然后有一个 4x4 矩阵,并用那个小矩阵在左上角的 3x3 部分进行“旋转”。当您可以使用 4x4 矩阵时,您应该能够将其应用于任何 MxN 矩阵(其中 M > 3 和 N > 3)。当您可以在纸上完成时,请尝试将算法改进为简单的小而离散的步骤。最后将这些小步骤转化为代码。
  • 您可以暂停计算旋转前和旋转后索引之间的九个差异的数组:diff[]={0-1,1-2,2-8,6-0,7-7, ...}。选择要旋转的子数组后,获取该子数组中的索引数组(例如,左下角的ix[]={8、9,10,24,25,26,30,31,32})并以某种方式a[k] 与@987654326 交换@ 代表每个k。 (somehow 部分意味着它只是一个原始想法,而不是解决方案。)

标签: c arrays rotation computer-science


【解决方案1】:

在这里区分事物在内存中的分配方式和您如何表示它们很重要。没有“6x6 一维数组”这样的东西,因为一维数组没有行和列。所以首先将这个 1D 数组转换为 6x6 的 2D 数组。

然后您可以通过指定坐标 (x, y) 来定义旋转中心。您应该仔细检查这些坐标,使它们不在矩阵的边缘(或者,如果需要,设计算法以使其成为可能)。


直接的解决方案是抓住中心周围的索引并以硬编码的方式移动数据:

array[center_x-1][center_y-1] = array[center_x][center_y-1];
...

等等。这将是最快的方法,最简单的解决方案往往是最好的。


允许可变旋转方向的更模块化的方法是创建一个指针数组,指向需要旋转的中心周围的数据。这个指针数组可以实现为一种简单的链表形式:

typedef struct rotate_node_t rotate_node_t;
typedef struct rotate_node_t
{
  rotate_node_t* next;
  rotate_node_t* prev;
  int* data;
} rotate_node_t;

你会有一个rotate_node_t rotation [8],它的索引可以分配为:

0 1 2
7 c 3
6 5 4

其中“c”是中心。

有了这个,您可以简单地在任何方向遍历链表并将数据从一个节点移动到另一个节点。它比直接数组访问更灵活,但速度更慢且更复杂。并且可以扩展为支持各种狂野的旋转模式。

【讨论】:

    猜你喜欢
    • 2016-06-11
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多