【问题标题】:Efficient data-structure for finding smallest substring having all the query words用于查找具有所有查询词的最小子字符串的有效数据结构
【发布时间】:2013-04-13 17:47:40
【问题描述】:

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

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

查询 1 :"Ram computer a" 输出:"Ram has a computer" 查询 2:“Ram home” 响应:“home.Ram”

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

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

【问题讨论】:

  • 我看不出将文件存储在链表中如何帮助您找到所说的最小子字符串..

标签: string algorithm data-structures processing-efficiency


【解决方案1】:

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

【讨论】:

  • 非常感谢您的回答,最后一部分对我来说不是很清楚。添加到优先级队列,删除然后添加到 BST..
  • @Amit:假设我们有 K 个查询词。那么优先级队列应该正好包含 K 个可能的起始位置。同时BST应该包含恰好K个对应的结束位置。优先级队列中的每个替换都允许查看每个(本地)最短的子字符串。而max_in_BST - min_in_queue 确定此子字符串的长度并允许选择全局最短的子字符串。可能other question 将有助于更好地理解这个“最后一部分”。
猜你喜欢
  • 2016-10-16
  • 2017-05-17
  • 2019-02-17
  • 1970-01-01
  • 2019-05-12
  • 2017-06-28
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
相关资源
最近更新 更多