【问题标题】:fastest way to do keyword search in large text in C/C++在 C/C++ 中以大文本进行关键字搜索的最快方法
【发布时间】:2011-10-28 07:29:54
【问题描述】:

假设我有 100 个关键字(可以包括空格),我需要找出它们在一大段文本中出现的次数。最快的方法是什么?

我目前的想法如下:

  • 将关键字变成后缀树
  • 遍历节点后面的文本,只要后缀树中没有出现字符(即 node->next == NULL),就跳到下一个单词并再次搜索

后缀树结构看起来像这样:

struct node {
   int count; //number of occurences (only used at leaf node)
   /* for each lower-case char, have a pointer to either NULL or next node */
   struct node *children[26];
};

我确信有一种更快的方法可以做到这一点,但它是什么?对于这种情况,空间效率并不是什么大问题(因此子数组可以更快地查找),但时间效率确实很重要。有什么建议吗?

【问题讨论】:

    标签: c++ c performance algorithm search


    【解决方案1】:

    如果是工业应用,请使用Boost Regex

    它已经过测试,速度很快,很可能会为您减轻很多痛苦。

    【讨论】:

      【解决方案2】:

      后缀树方法的问题在于,您必须为要搜索的文本的每个字母开始后缀搜索。我认为最好的方法是为文本中的每个关键字安排搜索,但使用一些具有预先计算值的快速搜索方法,例如Boyer-Moore

      编辑

      好的,您可以肯定尝试可能会更快。 Boyer-Moore 在一般情况下非常快。例如,考虑字符串的平均长度为 m。对于“正常”字符串,BM 可以与 O(n/m) 一样快。那将使100 * O(n / m)。 trie 的平均值为 O(n*m)(但在现实生活中它确实会快得多),所以如果 100 >> m 那么 trie 就会获胜。

      现在是关于优化的随机想法。在一些必须进行向后搜索的压缩算法中,我看到部分哈希表由字符串的两个字符索引。也就是说,如果要检查的字符串是c1c2c3的字符序列,则可以检查:

      if (hash_table[c1 * 256 + c2] == true) check_strings_begining with [c1,c2]
      

      然后是c2c3,以此类推。令人惊讶的是,您通过这种简单的检查避免了多少情况,因为这个哈希值只有每 100/65536 次 (0.1%) 为真。

      【讨论】:

      • 我知道 Boyer-Moore 非常快,但是对于重复关键字查找来说它也是最快的吗?我的意思是,“for(i=0;i
      【解决方案3】:

      你似乎在摸索着走向http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm

      引用:

      算法的复杂性与模式长度加上搜索文本的长度加上输出匹配的数量成线性关系。请注意,由于找到了所有匹配项,因此如果每个子字符串都匹配(例如,字典 = a、aa、aaa、aaaa 并且输入字符串为 aaaa),则可能有二次匹配数。

      【讨论】:

        【解决方案4】:

        这就是我会做的。

        1. 将所有关键字放在键值对的哈希表中,以关键字的出现次数作为值,将关键字作为(您猜对的)键。
        2. 对照哈希表检查文本 blob 中的每个单词。如果单词在哈希表中,则增加与其关联的出现次数。

        这是一个好方法,因为哈希表查找是(或应该)摊销 O(1) 时间。整个算法具有线性复杂度:)。

        编辑:如果您的关键字可以包含空格,则需要进行一种 DFA。扫描文件,直到找到一个关键“短语”开头的单词。如果第二个(或很多)下一个词是“关键短语”的一部分,则增加出现次数。

        【讨论】:

          猜你喜欢
          • 2011-05-16
          • 2010-09-17
          • 2016-10-25
          • 1970-01-01
          • 2012-02-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多