【问题标题】:Shrinking a circular buffer缩小循环缓冲区
【发布时间】:2013-07-05 11:02:37
【问题描述】:

我正在尝试实现循环缓冲区的收缩操作。 缓冲区有一个起始指针 (m_start) 并存储元素的数量 (m_numelements)。当缓冲区已满时,我只是清除旧值。

假设我们有一个大小为 16 的数组。 m_start = 9 m_numelements = 11。

我想把这个数组收缩成一个大小为 8 的数组(可以丢弃元素)。

这里的约束是旧数组的 m_start( 9 ) 应该映射到新数组的 m_start % 新容量 ( 9 % 8 = 1 )。

我尝试编写代码,但最终得到了很多 if-else 阶梯。有什么有效的实现吗?

【问题讨论】:

  • 我也有类似的问题。是否允许我编辑问题以使用更具体的实现(在 C 中),可能会强制更新一些答案建议(目前尚未接受),还是我应该问一个新问题?

标签: algorithm data-structures circular-buffer circular-list


【解决方案1】:

让我们的存储数组有从零开始的索引,它的大小是 2 的幂 (2,4,8...),m_start 是起始索引。

当数组增长时:

 double array length
 if m_start > 0 then
    copy (m_start elements) from (0th index) to (old size index) 

示例:

  3 0 1 2|. . . .
  . 0 1 2|3 . . . 

当数组缩小时:

  if m_start > 0 then
     copy (m_start elements) from (newsize index) to (0th index) 
  half array length  

示例:

  . 0 1 2|3 . . . 
  3 0 1 2|. . . .

您可以修改此方案以实现基于 1 的数组索引。

【讨论】:

    【解决方案2】:

    Shrinking 相当于将整个内容出列到一个临时缓冲区中,然后将该缓冲区的内容排入一个具有指定容量的新循环缓冲区中。这不是您想要的,但它会告知代码必须是什么样子。

    所以:编写代码以将循环缓冲区的全部内容出列,并使用您已有的方法将它们排入新的循环缓冲区,然后内联包含在您使用的方法中的代码,然后重构该代码以放置内容放入现有的循环缓冲区(调整大小后)而不是新的循环缓冲区,并优化掉任何不必要的副本或案例。

    【讨论】:

    • 对于大量项目,这在时间和内存方面可能效率低下。也许可以在stackoverflow.com/a/70659033/6607497 中查看图片,在某些情况下可以更有效地完成。
    猜你喜欢
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2021-09-01
    • 2016-06-11
    相关资源
    最近更新 更多