我的朋友在接受采访时遇到了这个问题。我们得到一个包含一些句子的文件。句子只有0-9,a-z,A-Z和句号(。),我们需要读取文件并以查询更快的方式存储它。这个阶段所花费的时间不是问题。这里查询将包含一些单词,我们需要返回包含所有这些单词的最小子字符串。订单并不重要。 (注意:假设整个文件可以放入主内存中)
例如,如果文件是:“Ram正在攻读计算机科学学位.Ram在家里有一台电脑.Ram现在在家。”
查询1:“Ram计算机a”输出:“Ram有一台计算机” 查询2:“拉姆之家”回复:“回家。拉姆”
我想将文件存储为链接列表,其中每个节点都由一个单词组成。如果是最后一个单词,则word + fullstop存储在节点中。在查询时,我们需要遍历LL并找到包含所有单词的最小字符串。
我们如何进一步优化它?我们能以更好的方式存储文件吗?
答案 0 :(得分:2)
您可以Suffix array的形式存储文件。它可以在O(N)时间内构造,其中N是文件的长度。可以在O(M + log N)时间内使用二进制搜索找到每个查询词,其中M是查询词的长度。如本文所示:"Replacing suffix trees with enhanced suffix arrays" by Mohamed Ibrahim Abouelhodaa, Stefan Kurtzb, Enno Ohlebusch,我们可以将其改进为O(M)。
由于预处理阶段所花费的时间不是问题,因此您可以使用Trie而不是后缀数组。只需将输入文件的每个单词添加到trie中,并将该单词在文件中的位置添加到该单词的位置列表中(每个trie节点需要一个这样的列表)。
在后缀数组或trie中找到所有查询字的位置后,你必须对它们进行排序(仅对于后缀数组,因为它们已经在trie的情况下排序),然后找到一组位置,彼此最接近: