缩写是一串字母数字字符。数字表示要跳过的字母数,例如i18n是国际化的缩写。 inter15和20也是如此。假设你有一个单词词典,找到字典中与给定缩写匹配的所有单词的最快方法是什么?您可以将任何数据结构用于字典,但查找匹配单词的算法必须优于O(n),其中n是字典中单词的数量。
答案 0 :(得分:1)
所以你的查询是prefix - count - suffix
。有几种方法可以解决这个问题。
如果前缀永远不会为空,那么您可以构建一个前缀树(它只是一个trie),并查询以该前缀开头的所有单词,过滤那些具有所请求长度和后缀的单词。
您可以通过构建generalized suffix tree来完成同样的事情。
或者,由于前缀或后缀可能为空,因此您可以构建前缀树和后缀树。查询两者,过滤长度,并将结果合并。
您可以设想构建一个前缀后缀树。数据结构比拥有两个单独的树要复杂一些,但它需要更少的内存。
我记得(已经有几年了),你可以使用有向无环字图(DAWG)完成所有这些以及更多(搜索缺少字母的单词等)。
答案 1 :(得分:0)
解决方案是对多个数组中的所有单词进行分类。每个数组都包含具有特定字母数量的所有单词。 例如,一个包含4个字母的数组,如:食物,木头,像,梭子鱼等。 另有5个字母等等。
因此,在你的缩回i18n中,你将字符和数字分开:“在”“18”中你将字符数量加到数字上:2 + 18 = 20。现在你知道你的单词是20个字母的单词数组。
我认为我们可以做得更好,但这比在整个词典中找一个单词要好。
答案 2 :(得分:0)
这是a10n树的一个想法(缩写树,或者应该是a10n t2e?)。
缺少的字母将由缺失的块的长度替换,因此匹配的长度事先已知。将字典细分为包含恒定长度字的子字典是有意义的:
dict -> dict2 -> {ad, ah, am, an, as, at, ...}
-> dict3 -> {abe, abo, abu, ace, act, ada, add, ... }
-> dict4 -> {abba, abbe, abby, ...}
-> ...
每个词典都包含一个有序的单词列表。如果缩写是,例如“5”,则返回长度为5的子字典的列表。如果缩写为“绿色”,即根本没有缩写,请使用二分查找检查该单词是否在列表中。
在满足琐碎案件的情况下,我们必须找到一种快速搜索此列表的方法。让我们介绍一个位置和字母树。树的第一层指的是字母的位置,第二层指的是字母本身,就像在trie中一样,例如:
dict3 -> i == 0 -> a -> {ant}
-> b -> {bat, bee}
-> c -> {cat, cod, cow}
-> ...
i == 1 -> a -> {bat, cat, rat}
-> b -> {}
-> c -> {}
-> ...
现在找到所有给定字母的列表的交集。如果我们正在寻找“c2”,我们将列表放在(0,c)。如果我们正在寻找“b1t”,我们采用(0,b)和(2,t)处的列表的交集。订购列表时,找到交叉点应该相当快。
还有其他方法。尝试是一种数据结构,允许我们快速搜索字典。 我在对一篇现已删除的帖子的评论中说过,在这种情况下,我认为尝试不是一个合适的数据结构,因为当第一个字母已知时,尝试有助于查找单词。但是我现在不太确定:当发现一个通配符,即一个丢失的字母时,可以下降一个特里的所有分支。对于像'i18n'这样的单词,分支的数量似乎相当大,但在实践中,会有很多空分支。在我的(小)测试词中,大约45,000个单词,没有任何词匹配'i18n',甚至没有国际化。因此,对于真实的词典,尝试甚至可能是一种选择。
(向删除答案的用户道歉,但我在评论中提到了dict的单个trie。如果字典不是庞大的话,每个长度的子测试可能会有用。)