用于存储单词列表的节省空间的数据结构?

时间:2008-12-11 01:54:52

标签: java data-structures

对于这种情况,有没有比Trie更好的东西?

  • 存储~100k英文单词列表
  • 需要使用最小内存
  • 查找需要合理,但不必快速闪电

我正在使用Java,所以我的第一次尝试就是使用Set< String>。但是,我的目标是移动设备并且内存不足。由于许多英语单词共享共同的前缀,trie似乎是一个体面的赌注,以节省一些记忆 - 任何人都知道一些其他好的选择?

编辑 - 更多信息 - 数据结构将用于两个操作

  • 回答:列表中是否有XYZ字样?
  • 生成XYZ周围的单词邻域,字母不同

感谢您提出的好建议

6 个答案:

答案 0 :(得分:8)

我看到一个最小化拼写字典空间的结构是将每个单词编码为:

  • 与最后一个共同的字符数(一个字节);和
  • 新结局。

所以单词列表

HERE            would encode as    THIS
sanctimonious                      0,sanctimonious
sanction                           6,on
sanguine                           3,guine
trivial                            0,trivial

你在那里直接保存7个字节(19%),我怀疑由于相邻单词的(公共前缀)之间的最小距离,对于20,000字的字典保存是相似的。

为了加速查找,内存中有一个26条目表,它保存以a,b,c,...,z开头的单词的起始偏移量。这些偏移处的字总是以0作为第一个字节,因为它们没有与前一个字相同的字母。

这似乎是一种特里但没有指针,如果树中的每个字符都有一个与之关联的4字节指针,这肯定会占用太多空间。

请注意,这是来自我的CP / M日,那里的记忆比现在更加稀缺。

答案 1 :(得分:6)

Patricia trie可能更合适:

http://en.wikipedia.org/wiki/Patricia_tree

我的(模糊)记忆告诉我在一些早期的全文搜索引擎中使用过......

保罗。

答案 2 :(得分:3)

你正在做什么?如果是拼写检查,您可以使用布隆过滤器 - 请参阅此code kata

答案 3 :(得分:1)

您仍然需要使用Trie维护树结构。 Huffman encoding字母或N字母(对于“ing”,“un”,“ing”等常见形式)可以利用字典中的出现频率并将条目压缩为位。

答案 4 :(得分:1)

完全疯狂的想法......(即很可能非常错误)

如何将单词存储为所有可能字母组合的树?

然后每个“单词”只花费一个char和两个指针(一个指向char,一个指向终结符。)这样,它们共有的字母越多,每个单词的成本就越少。

      . .
     / /
    r-p-s-.
   /\\
  a  \s-.
 /    t-.
c      \
        s-.

车 鲤鱼 鲤鱼 汽车 大车 推车

因此,对于9个字符和14个指针,我们得到6个“单词”,总共25个字母。

搜索会很快(指针查找而不是字符比较),你可以做一些词干优化来节省更多的空间......?

编辑:看起来我重新发明了轮子。 ; - )

答案 5 :(得分:1)

与保罗的帖子相关:

为什么你不能在你的情况下考虑特里?如果它只是一个实现问题,这里是Patricia trie插入和C搜索(来自NIST)的紧密实现:

Patricia Insert in C

Patricia Search in C