【问题标题】:Circular Buffer Comparison / Lookup Algorithm循环缓冲区比较/查找算法
【发布时间】:2013-06-13 01:20:30
【问题描述】:

我想检测一个循环缓冲区是否是相同长度的其他缓冲区列表的镜像或旋转。

例如给定以下 3 个缓冲区:

AAABCCCA
AABCCBAA
AAAACCAA

然后: CCBAAAAC 会匹配,因为它是第一个缓冲区的镜像旋转。

目前我只是比较每次旋转中的每个缓冲区,然后反转缓冲区并再次执行所有操作。

这需要: 2*n*i 缓冲区比较。 (其中 n 是要比较两个的缓冲区的数量,i 是缓冲区的长度)。

有人知道更快的算法吗?

要比较的列表越来越多(因为我发现一个不在我拥有的列表中)。有没有一种方法可以让我以某种方式“订购”缓冲区,以便可以更快地进行比较?

我的一个想法是存储每个缓冲区的排序版本,以便您可以快速比较是否存在相同数量的项目。

但是是否有更通用的解决方案来以某种方式按“循环序列”排序?

【问题讨论】:

  • 加倍搜索模式,然后在其中查找完全匹配。 ??
  • 这与我所说的基本相同。模式匹配将在 n 个字符串中查找 i 个位置,对于 2*n*i,您必须向后执行。但是,您所说的是使用 strstr 等标准函数对其进行编码的最简单方法。

标签: algorithm sorting buffer circular-buffer


【解决方案1】:

对于每个缓冲区,您可以旋转它,直到它具有最小的字典值。

例如,您的示例缓冲区可以像这样旋转:

AAABCCCA -> AAAABCCC
AABCCBAA -> AAAABCCB
AAAACCAA -> AAAAAACC

这基本上意味着将价值最低的物品放在第一位。如果出现平局,则比较下一个项目等。这为任何模式提供了唯一的排序。

【讨论】:

  • 哇。我不知道为什么我没有意识到这一点。许多缓冲区在我脑海中旋转。我可以这样做,然后按字典顺序对它们进行排序,这意味着我可以进行二进制搜索。然后缓冲区比较的次数将从 2*i*n 下降到 log(n)。
  • 您可以存储/查找旋转后的原件和旋转后的镜像之间的最小字典值,而不是同时存储两者。 @Myforwik 应该是 i log n 而不仅仅是 log n。我认为您可以使用类似trie 的结构来降低到O(i)
  • @Myforwik 哦,“缓冲比较”。那么log n 是正确的。 Trie 是 i.t.o 字符比较,而不是缓冲区比较。一种更常见的方法是计算字符比较。
猜你喜欢
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 2012-05-12
  • 2019-06-08
相关资源
最近更新 更多