用于查找具有所有查询词的最小子串的高效数据结构

时间:2013-04-20 11:26:36

标签: string algorithm data-structures processing-efficiency

我的朋友在接受采访时遇到了这个问题。我们得到一个包含一些句子的文件。句子只有0-9,a-z,A-Z和句号(。),我们需要读取文件并以查询更快的方式存储它。这个阶段所花费的时间不是问题。这里查询将包含一些单词,我们需要返回包含所有这些单词的最小子字符串。订单并不重要。 (注意:假设整个文件可以放入主内存中)

例如,如果文件是:“Ram正在攻读计算机科学学位.Ram在家里有一台电脑.Ram现在在家。”

查询1:“Ram计算机a”输出:“Ram有一台计算机” 查询2:“拉姆之家”回复:“回家。拉姆”

我想将文件存储为链接列表,其中每个节点都由一个单词组成。如果是最后一个单词,则word + fullstop存储在节点中。在查询时,我们需要遍历LL并找到包含所有单词的最小字符串。

我们如何进一步优化它?我们能以更好的方式存储文件吗?

1 个答案:

答案 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的情况下排序),然后找到一组位置,彼此最接近:

  1. 将所有查询字的最小位置添加到优先级队列(可以实现为min-heap),
  2. 虽然此优先级队列中顶部字的尚未处理的位置列表不为空,但将最顶层的队列条目替换为同一字的下一个位置。每次从优先级队列中添加/删除某些条目时,将相应单词结尾的位置添加/删除到某个有序集合(如二叉搜索树)。此集合中的最大条目与优先级队列中的最小条目之间的差异允许确定具有所有查询字的最小子字符串。