从尾部移除时将元素添加到数组头部

时间:2015-12-14 21:50:37

标签: c arrays

我有一个恒定大小的数组x(通常大约100-200个条目),并希望在头部添加一个常数较小(通常在2-10个条目之间)的数组y,同时删除相同的大小结束。例如:

缓冲液:     x = [6 5 4 3 2 1]

要添加的新数组:     y = [8 7]

产生的缓冲区:     x = [8 7 6 5 4 3]

等等......

注意:我需要使用常规C数组,并且需要能够访问整个数组,而不仅仅是头部或尾部。该数组相当小,但该函数经常被调用,所以我正在寻找一个不需要任何过多内存任务的解决方案。在每一步中,数组x和y的大小始终相同。

这是缓冲区,循环/环形缓冲区,队列还是FIFO?我真的不知道这个应用程序的正确搜索词是什么。

语言是C.

4 个答案:

答案 0 :(得分:2)

如何使用memmove()中的<string.h>来移动数组的切片?如果没有实际测量性能,那就不能排除。使用链表的任何解决方案都可能涉及比高度优化的memmove()(编译器甚至内联)更长的操作。

这实际上取决于

  • 数组中元素的数量
  • 元素类型的大小
  • 操作的频率
  • 相对于其他所有内容修改数组的时间

答案 1 :(得分:2)

如果您需要线性访问数组内容,并且您不想执行频繁的memcpy操作,可能的解决方案是翻转缓冲区滑动缓冲区< /强>

翻转缓冲区的大小是数组需要的两倍(如果你愿意的话,甚至更多),这样你就可以在添加到结尾时只移动一个尾指针,而不需要任何环绕,保持数据的线性。

当您达到底层缓冲区的硬限制时,则执行滑动操作:将数组的上半部分移动到下半部分,并从所有索引中减去相同的增量。

当这个幻灯片操作发生时,你知道现在所有的数据和索引都在上层分区,因为缓冲区2 * N,宽度从不包含超过N个条目:它是模拟的一个N大小的环形缓冲区。也就是说,情况永远不会出现尾部已经到达缓冲区的末尾,但是头部仍然在下部分区中(有超过N个项目。)

由于您想要添加到前面,我们首先填充上部分区,然后向上翻转:

 [x x x x x x | 6 5 4 3 2 1 ]   -- six-element queue, twelve el. buffer
            H             T

 Add 8 7, remove 2 1:

 [x x x x 8 7 | 6 5 4 3 x x ]
        H             T

 Add 2 1 0 9, remove 6 5 4 3:

 [2 1 0 9 8 7 | x x x x x x ]
H           T

头部已达到-1!使用memcpy翻转到上部分区,在头部和尾部添加6:

 [x x x x x x | 2 1 0 9 8 7 ]
            H             T

请注意,由于这两个分区不重叠,因此我们不必使用memmove:我们可以使用memcpy

答案 2 :(得分:0)

您需要的是索引偏移量。因此,每次“插入”值时,只需将它们写在虚拟尾部所在的位置并更新索引偏移量。这就是循环缓冲区的工作原理。

答案 3 :(得分:0)

这是重复的。以下是代码审核https://codereview.stackexchange.com/questions/64258/array-implementation-of-queue中的Java实现以及此处C Queue using Arrays中的一个问题。