给定一个随机字符串,我想找到字典中只包含那些字母的每个单词。输入字符可以忽略,因此对于字符串“ccta”,我们可以找到“act”或“cat”。
我应该如何实现数据结构来实现这一目标?
它可能只是一个纯文本文件,但这会很慢而且没有趣味。我的想法是首先为给定的字符串构建频率图:
{{1}}
然后我将构建一些可以通过这样的频率图“索引”的数据结构。我可以将字典转换成这样的结构,搜索速度非常快。
通过这样的频率图索引字典的最佳方法是什么?
答案 0 :(得分:2)
对于字典部分,我认为您可以使用Trie数据结构。 您可以了解有关它的更多信息here和一个好的实现(在C中)和教程here。
它本质上是一个搜索树,可以存储字符串,或者更确切地说字符串前缀,使其成为实现字典的理想选择。
您可以先为字典中的单词构建Tries。例如,每个字母表都有一个trie,以便所有以该字母开头的单词存储在一起。
对于搜索部分,解决方案(虽然效率稍低)可能是生成给定字符串的所有排列,并在创建的尝试中搜索它们。如果找到与置换字符串的任何前缀匹配,则也可以返回它。
答案 1 :(得分:0)
1)对每个单词中的唯一字母进行排序。然后创建一个字典,将每个排序字母字符串映射到单词列表包含完全相同的字母。
2)制作包含所有排序字母字符串的Patricia trie(https://en.wikipedia.org/wiki/Radix_tree)。
要进行搜索,请首先制作一组有效字母。然后,您可以在Patricia trie上进行深度优先搜索,以查找仅包含这些字母的所有条目,并展开相关的单词列表。这是一个正常的深度优先搜索,除了当它包含一个不在有效集合中的字母时停止跟踪路径。
对单词字符串进行排序时,请使用将最不常见的字母放在第一位的排序。这样,trie会变浅,你的DFS平均需要搜索更少的分支。
答案 2 :(得分:0)
在算法方面,有办法将每个单词缩减成一个键:
然后使用字典key -> [word]
似乎是一个合理的选择。
对于密钥,我建议使用排序Vec<char>
,因为它可能比BTreeMap
更有效。最值得注意的是,向量只有一个内存分配,而且它的比较是直截了当的memcmp
。
对于字典,我建议使用HashMap
:HashMap<FreqMap, Vec<String>>
。
如何从 actt 转到行为和 cat ?
效率最高,但您无法将所有可能的输入存储在内存中。
备注:char
是unicode代码点,但不是字形代码。根据您处理的语言/字符串,这可能很重要;例如,如果字母á
é
分别编码为a
+ ´
和e
+ ´
,则aé
和áe
会产生相同的密钥(a
:1,e
:1,´
:1),即使它们不同。