【问题标题】:Longest substring in a large set of strings一大串字符串中最长的子串
【发布时间】:2012-07-11 03:13:03
【问题描述】:

我有一个庞大的固定文本字符串库,以及一个经常变化的输入字符串 s。我需要在最短的时间内从库中的任何字符串到 s 中找到最长的匹配子字符串,从字符串 s 的开头开始。在一个完美的世界中,我还会从库中返回下一个最长的匹配,以及下一个最好的匹配,依此类推。这不是最长的公共字符串问题——我不是在为库中的所有字符串寻找最长的公共字符串......我只需要尽可能快地在 s 和庞大库中的每个字符串之间找到一个成对的最佳子字符串。

【问题讨论】:

  • 匹配字符串是否应该在它们的第一个字符处匹配,例如abcdabef?或者abcdbcde 也是匹配的?

标签: c


【解决方案1】:

重读后,我认为最好的方法可能是为你的大字符串库构建一个 trie 或前缀树,然后匹配 s

这有几个优点。首先,它以(至少在某种程度上)压缩形式存储您的大型库。其次,它或多或少会自动告诉您与给定输入匹配的所有字符串,而不仅仅是最长的字符串。

它也非常适合您的用例 - 虽然从输入构建 trie 或(尤其是)前缀树需要大量工作,但之后使用它非常快。

【讨论】:

  • 这基本上是一个最长前缀匹配搜索,trie 非常适合。您在输入字符串上逐个字符地迭代 trie 键控,直到您无法再进一步。如果您在用尽输入字符串时或之前点击了叶节点,那么这就是您的匹配项。如果您位于非叶节点,则从该节点下降的所有字符串都将输入字符串的任何部分(可能全部)匹配为前缀
  • 只是一个旁白,在标准 C (AFAIK) 中没有红黑或任何其他树,也没有散列。因此,bsearch 是标准中唯一可以开箱即用的算法。
【解决方案2】:

提前(即编译时间或之前)对列表进行排序,然后使用 bsearch

http://www.cplusplus.com/reference/clibrary/cstdlib/bsearch/

找到匹配项后,您可以在附近前后查看,以获得尽可能多的“匹配项”。

顺便说一句,bsearch 不一定是最快的,因为它通过了比较器函数,但在标准 C 库中。

【讨论】:

  • 除非每个较长的字符串都是每个较短字符串的扩展,否则这是行不通的。即使较短的字符串不匹配,较长的字符串也可能匹配。
  • @Jerry 如果它们按字母顺序排序,不是这样吗?此外,OP 可以定义比较器功能,因此“匹配”取决于他们。我假设子字符串从列表中字符串的位置 0 开始。这可能不是 OP 的意图。
  • 啊,现在我明白了。是的,如果它必须从位置 0 开始,这会很好地工作。我以为这不是必需的,但重新阅读,我很确定你是对的——他确实指定了“从字符串 s 的开头开始”。
猜你喜欢
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 2013-02-21
  • 2014-06-03
  • 1970-01-01
相关资源
最近更新 更多