查找与查询匹配的所有名称:如何使用后缀树?

时间:2016-05-21 15:39:06

标签: string algorithm data-structures suffix-tree

问题:您有一部智能手机并且您打开了联系人应用程序。您想要搜索联系人。让我们说manmohan。但你不记得他的全名。你只记得mohan,所以你开始输入。在您输入“ m ”联系应用的那一刻,我们将开始搜索可用字母“ m ”的联系人。假设您已在联系人列表("manmohan", "manoj", "raghav","dinesh", "aman")中存储了名称,现在联系人将显示manmohan,manoj and aman。现在你输入的下一个字符是' o '(直到现在你输入了“ mo ”)现在结果应该是“man mo han ”。你会如何实现这样的数据结构?

当你在所有可用的联系中寻找模式“m”然后“mo”时,我的方法是应用KMP。然后显示具有匹配项的字符串。但是面试官说这不高效。 (我想不出更好的方法。)在离开之前,他说有一种算法会有所帮助。如果你知道它就可以解决它。我不能这样做。 (离开之前我问过那个标准算法。采访者说:后缀树)。谁能解释一下请问它有什么好转的?或哪个是实现此数据结构的最佳算法。

1 个答案:

答案 0 :(得分:1)

您尝试解决的问题基本上归结为以下内容:给定一个固定的字符串集合和一个仅通过追加更改的字符串,您如何有效地查找包含该模式作为子字符串的所有字符串?

在字符串上有一个简洁的结果,这对于处理涉及子字符串搜索的问题通常很有用:字符串P是字符串T的子字符串当且仅当P是T的至少一个后缀的前缀时(Do)你知道为什么吗?)

因此,想象一下,你在你的单词库中取出每个名字,并构建该行中所有单词的所有后缀的trie。现在,给定要搜索的模式字符串P,沿着trie向下,读取P的字符。如果从trie上掉下来,那么字符串P不能是任何名称库的子字符串(否则,它本来是T)中一个字符串的至少一个后缀的前缀。否则,你在某个节点上。然后根据您当前访问的节点的子树中的所有后缀对应于T中所有名称中子字符串的所有匹配,您可以通过DFS-subtrie找到并记录所有后缀找到。

后缀树本质上是一种节省时间和空间的数据结构,用于表示字符串集合的所有后缀的三元组。它可以按照与T中总字符数成比例的时间建立(虽然这样做的算法很难直观和编码),并且设计为可以找到所有根据问题的文本字符串匹配。给定节点的时间O(k),其中k是匹配的数量。

回顾一下,这里的核心思想是在T中创建字符串的所有后缀,然后使用模式P向下走。为了时间和空间效率,你用后缀< em> tree 而不是后缀 trie