C++,用于在大文件中的行上搜索单词的算法

C++, Algorithm for searching for a word on a line in a large file?

本文关键字:单词 算法 搜索 用于 文件 C++      更新时间:2023-10-16

我正在尝试找到查找大文件中哪些行包含某个单词的最佳方法。

例如,如果您有以下文件:

cat dog monkey 
banana chair elephant 
monkey phone platypus cat

我希望它能够为"猫"返回 0, 2

我希望函数原型看起来像这样:

std::vector<int> FindWords(std::string word);

我想将文件预处理为某种数据结构,以便可以快速完成锁定,给出包含单词的行号。我知道 std::map 可以做到这一点,如果这个词只有一个实例,但还有更多。

最合适的算法是什么?

为文件中的所有唯一单词构建 trie 数据结构。

对于 trie 中的每个单词,存储文件中存在该单词的行号列表。这可以通过单次传递文件来完成。

您也可以使用地图来存储每个单词的行号列表,但trie会更紧凑。

下面添加了 trie 数据结构的 C 声明。这应该让您了解如果您想实现自己,如何开始。

/*
 * TRIE data structure defined for lower-case letters(a-z)
 */
typedef struct trie {
  char c;                           /* Letter represented by the trie node */
  struct trie *child[26];           /* Child pointers, one for each of the 26 letters of the alphabet */
  bool isTerminal;                  /* If any word ends at that node, TRUE, else FALSE */
  int counts;                       /* Number of lines the word ending at node occurs in the text */
  int lines[MAX_NUM];               /* Line numbers of the word occurences in the text */
} trie;
/*
 * Insert a word into the trie.
 * word - Word which is being inserted
 * line - Line number of word in the text.
 */
void insertToTrie(trie *node, const char *word, int line);
你也可以使用 std::

multimap 或者更好的 std::unordered_multimap,因为你不需要只在某个值的元素上遍历整个 map 集合。

编辑:简单的例子:

#include <iostream>
#include <unordered_map>
int main() {
   std::unordered_multimap<std::string, int> mymap;
   mymap.insert(std::pair<std::string, int>("word", 1));
   mymap.insert(std::pair<std::string, int>("anotherword", 2));
   mymap.insert(std::pair<std::string, int>("word", 10));
   for (auto it = mymap.find("word"); it != mymap.end() && it->first == "word"; it++) {
      std::cout << it->second << std::endl;
   }
}

当您搜索单个字符串时,Boyer-Moore字符串搜索算法比trie更快。您很可能可以为多个字符串修改它。