【问题标题】:Efficient algorithm to search a buffer for any string from a list从列表中搜索任何字符串的有效算法
【发布时间】:2015-02-11 03:34:42
【问题描述】:

我正在寻找一种有效的搜索算法,即对于给定的字符串集,在一个大缓冲区中搜索字符串集中的任何一个匹配项。 目前我知道一些高效的单字符串算法(我以前使用过 Knuth),但我不知道它们是否真的有帮助。

这是我实际在做的事情:

  • 我有大约 6-10 个预定义字符串,每个大约 200-300 个字符(实际上是字节,因为我正在处理二进制数据)
  • 输入是一个很大的缓冲区,有时只有几兆字节
  • 我想处理缓冲区,当我找到匹配项时,我想停止搜索

我已经使用一组有限的预定义模式寻找多字符串搜索算法,但它们似乎都围绕匹配缓冲区中的所有预定义字符串。

这篇文章:Fast algorithm for searching for substrings in a string,建议使用 Aho-Corasick 或 Rabin-Karp alogirthm。

我想,既然我只需要一个匹配,我可以找到与上述算法类似的其他方法,但问题给出的约束可以提高性能。

【问题讨论】:

  • 您可能会从字符串集中构造一个正则表达式,并使用它来搜索数据。不过,我不知道这是否会“有效”,这只是我脑海中浮现的第一个想法。
  • Boyer-Moore 可能在这里提供帮助。 en.wikipedia.org/wiki/… 请注意,算法从包含文本中不常见的一组受限值的长模式中获得优势。您的模式相对较长,约为文本长度的 1%,如果您选择 long 的“字母表”,则第二个条件可能成立,除非模式和文本之间存在密切关系。注意:如果您的模式是“奇数”长度(不是 0 mod sizeof(long),您将需要对尾随奇数端做一些最后的检查。希望这是有道理的。
  • 我在想也许可以将 Aho-Corasick 和 Boyer-Moore 结合起来。如果没有简短的搜索模式,那么组合可能会非常快。结果可以成为一篇非常好的研究论文!
  • @DanAllen 您还需要处理对齐问题和一个非常大的跳转表。如果您有模式“ABC”和一个双字节字,则需要将“AB”和“BC”都放入跳转表(请注意,修复对齐问题也修复了“奇数长度”问题)。

标签: c string algorithm search


【解决方案1】:

Aho-Corasick 是个不错的选择。构建自动机后,输入字符串从左到右遍历,因此可以在找到第一个匹配项后立即停止。时间复杂度为 O(所有模式的长度之和 + 第一次出现的位置)。这是最佳的,因为如果不读取第一次匹配之前从缓冲区中读取的所有模式和所有字节,就不可能找到第一个匹配项。

【讨论】:

  • 感谢您清理它。那我就用这个方法
  • 只是一个简短的说明:实现了一个测试应用程序,它按我的预期工作,但是原始论文中的以下语句有点麻烦:“我们的问题是定位和识别 x 的所有子字符串是 K 中的关键字。” stat 是否仍然意味着它将遍历所有输入文本并且不会在第一次匹配时停止?
  • @user2281752 如果你自己实现这个算法,你可以在第一次匹配后停止。如果您使用的是现有实现,它可以查找所有匹配项(但该算法的性质不会阻止您仅查找第一个匹配项)。
猜你喜欢
  • 2012-01-29
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
相关资源
最近更新 更多