用于快速搜索由给定字母组成的单词的数据结构

时间:2016-11-14 17:38:52

标签: algorithm data-structures rust

给定一个随机字符串,我想找到字典中只包含那些字母的每个单词。输入字符可以忽略,因此对于字符串“ccta”,我们可以找到“act”或“cat”。

我应该如何实现数据结构来实现这一目标?

它可能只是一个纯文本文件,但这会很慢而且没有趣味。我的想法是首先为给定的字符串构建频率图:

{{1}}

然后我将构建一些可以通过这样的频率图“索引”的数据结构。我可以将字典转换成这样的结构,搜索速度非常快。

通过这样的频率图索引字典的最佳方法是什么?

3 个答案:

答案 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

对于字典,我建议使用HashMapHashMap<FreqMap, Vec<String>>

如何从 actt 转到行为 cat

  • 搜索 actt ,找到智慧(以及其他人)。
  • 搜索行为 att ctt (每次删除一个字母)并找到行为,< strong> cat 和 tat
  • ...

效率最高,但您无法将所有可能的输入存储在内存中。

备注:char是unicode代码点,但不是字形代码。根据您处理的语言/字符串,这可能很重要;例如,如果字母á é分别编码为a + ´e + ´,则áe会产生相同的密钥(a:1,e:1,´:1),即使它们不同。