【问题标题】:Which is perfect Data Structure for exact string pattern matching?哪个是精确字符串模式匹配的完美数据结构?
【发布时间】:2012-06-13 07:41:25
【问题描述】:

我正在研究网页内容过滤,其中一个页面上有 10000 个单词。我必须将它与我的 1500-2500words 词典相匹配。而且我必须找出页面中是否存在任何单词。

请建议我最好的数据结构来存储我的模式更快的搜索。 我研究过树结构。但是让我们取一个可能有 26 种可能的下一个字符的单词 (abc)。我必须为下一个节点保留 26 个指针。 (它消耗 26x4 字节)。我不能花那么多内存来存储每个单词的模式。

建议我最好的搜索和最好的记忆。

我是这个领域的初学者。

【问题讨论】:

  • 使用 trie,您不必“为下一个节点保留 26 个指针”。您可以动态分配排序指针数组。

标签: data-structures pattern-matching


【解决方案1】:

Aho-Corasick 完全解决了您的问题。经过一些预处理后,您可以在 O(n) 时间内处理每个网页,其中 n 是该页面的大小。您将需要与您的字典差不多大的辅助存储量。

您的内存限制似乎非常严重,但如果您确实需要减少内存占用,您可以使用在给定状态下存在的所有字符的列表,而不是在每个状态下使用 26 个字符的数组。在处理网页时,您需要浏览这些字符,这会大大降低您的速度,但您会节省空间。

【讨论】:

  • 我已经为 2000 个模式实现了 aho-corasick,每个模式由 121-123 个字符组成。我已经创建了下一个链接和后缀链接(失败链接)以便更快地搜索。但 293046 个字符消耗 4.5Mb。我们可以把这棵树缩小到 1MB。
  • 我的结构是:struct _treenode { char ch;短 int 孩子; //(用于下一个孩子的计数) char *value; //(用于存储模式名称) struct _treenode **next; //(下一个子链接) struct _treenode *suffixlink; //(失效链接) };
  • 如果你真的想节省空间,我建议如下: 1. child:这个值只能和你的字母一样高,所以它应该只是一个字节。 2.值:不要将名称存储为指针,我假设您将这些名称放在某个地方,因此只需将索引存储到该数组中即可。该指针(假设您在 32 位系统上)占用四个字节,但如果您只有 2k 个字,那么您只需要两个字节来索引到该大小的数组。如果您可以执行 1 和 2,那么您将节省 25% 的空间,因为您的结构将从 16 个字节减少到 12 个。至少这是一个开始。
  • 我还建议将 next 和 suffixlink 索引放入数组中,只要您的状态少于 2^16 个(但您可能不会)。
【解决方案2】:

最好的搜索是尝试http://en.wikipedia.org/wiki/Trie 为了获得最佳记忆和搜索的复杂性,我建议您使用http://en.wikipedia.org/wiki/Suffix_arrayhttp://en.wikipedia.org/wiki/Suffix_tree 另一种方法是通过对字典(O(NlogN))和单词 O(MlogM)进行排序,然后通过一次遍历检查每个元素是否匹配 O(N + M)。 您从 2 个索引开始,并且在每一步中,您根据将一个索引处的字典字符串与您在第二个索引处的单词进行比较的结果来增加其中一个索引,如果它们匹配,则您有一个匹配项并转到下一个。您拥有的单词,否则如果您的单词低于字典单词,则转到下一个单词(因为您之前已经浏览了所有字典单词并且没有找到匹配项)否则您转到字典中的下一个元素(试着在字典里找一个不低于你的单词的单词)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    相关资源
    最近更新 更多