【问题标题】:Rotate left an Array in C without a for?在没有 for 的情况下将 C 中的数组向左旋转?
【发布时间】:2018-11-30 10:32:48
【问题描述】:

我正在编写代码,我需要多次向左旋转数组。问题是我使用了for 循环。

当我需要使用带有短数组的函数时,它很快。但是,一旦我使用包含 10.000 个或更多元素的数组,由于for 循环,它真的很长。

所以我想知道是否有另一种方法可以在不需要forwhile(或任何其他循环)的C 中旋转数组?

void rotate_left(int *array, int size)
{
    int nb = array[0];

    for (int i = 0; i < size; i++) {
        array[i] = array[i + 1];
    }
    array[size - 1] = nb;
}

【问题讨论】:

  • 这是你应该使用链表而不是数组的地方。然后只需将一个节点从列表的开头移动到结尾即可。
  • 数组的问题是它们在内存中连续存储。因此,将其向左移动/旋转意味着接触所有元素。对于许多移位/旋转查询和大型数组来说,这会变得很慢。正如@Lundin 所说:链表更适合此任务并且在恒定时间内运行(如果您可以访问头部和尾部)。
  • 好的,我试试,谢谢!
  • 这种数据数组通常被编码为循环缓冲区(参见en.wikipedia.org/wiki/Circular_buffer),通过简单地更新头和尾指针,所有访问都可以非常快速地进行。
  • 你的轮换方式不对:int rot[5]={1,2,3,4,5}; rotate_left(rot,2); 输出:rot[0]:2 rot[1]:1 rot[2]:3 rot[3]:4 rot[4]:5

标签: c for-loop time rotation


【解决方案1】:

有没有办法在 C 中不循环地旋转数组?

没有

数组存储在连续内存中,因此任何移位都意味着线性访问其元素。

至少不是一个明确的。我的意思是有Circular Buffer,它使用固定大小的缓冲区,但它比数组更复杂。例如,当该缓冲区已满时,您需要用新元素覆盖最旧的元素。我想你不想那样。


我正在编写代码,我需要将数组向左旋转多次。

这要求使用简单的链表,而不是数组。

在列表的情况下,您只需将开始处的节点移动到列表的末尾。

如果你在网上搜索“向左旋转一个简单的链表”,你会发现很多例子。

【讨论】:

  • 我认为有一种方法可以实现数组元素旋转,按位移动数组元素。
  • 最后@EsmaeelE,它仍然需要访问元素,而使用列表则不需要。
【解决方案2】:

坚持数组:

如果你将缓冲区加倍并将数组复制到它自己的一端,你可以使用

void rotate_left(int **array, size_t size, size_t *shiftd){
    if(++*shiftd >= size){
        *shiftd %= size;
        *array -= size;
    }
    ++*array;
}

假设init() 函数多次运行相同,您可以像这样创建数组:

int *array = malloc(2 * size * sizeof(int));
init(array, size);
init(array + size, size);
size_t shiftd = 0;

并使用旋转功能

rotate_left(&array, size, &shiftd);

这应该演示转移的过程

array
 v
[1|2|3|1|2|3]
------- size = 3, shiftd = 0
[1|2|3]

***rotate_left(&array, size, &shiftd);***

  array
   v
[1|2|3|1|2|3]
  ------- size = 3, shiftd = 1
  [2|3|1]

***rotate_left(&array, size, &shiftd);***

    array
     v
[1|2|3|1|2|3]
    ------- size = 3, shiftd = 2
    [3|1|2]

***rotate_left(&array, size, &shiftd);***

array
 v
[1|2|3|1|2|3]
------- size = 3, shiftd = 0
[1|2|3]

但这不适用于以零结尾的字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    相关资源
    最近更新 更多