在这种情况下,有比Trie更好的选择吗?
- 存储约100k个英语单词列表
- 需要使用最少的内存
- 查询需要合理,但不必非常快
我正在使用Java,所以我的第一次尝试是只使用Set<String>。然而,我针对的是移动设备,内存已经很低了。由于许多英语单词共享公共前缀,使用Trie似乎是节省一些内存的不错选择 - 有没有其他好的选择?
编辑 - 更多信息 - 数据结构将用于两个操作
- 回答:列表中是否包含某个单词XYZ?
- 生成周围与XYZ相差一个字母的单词邻域
感谢好的建议
在这种情况下,有比Trie更好的选择吗?
我正在使用Java,所以我的第一次尝试是只使用Set<String>。然而,我针对的是移动设备,内存已经很低了。由于许多英语单词共享公共前缀,使用Trie似乎是节省一些内存的不错选择 - 有没有其他好的选择?
编辑 - 更多信息 - 数据结构将用于两个操作
感谢好的建议
我看到的一种减少拼写字典空间的结构是将每个单词编码为:
因此,单词列表变为:
HERE would encode as THIS
sanctimonious 0,sanctimonious
sanction 6,on
sanguine 3,guine
trivial 0,trivial
zwiebacks -> zygote common= old=1044662 new=469762 55.0%
zygote -> zygotes common=zygote old=1044670 new=469765 55.0%
zygotes -> zygotic common=zygot old=1044678 new=469769 55.0%
zygotic -> zymase common=zy old=1044685 new=469775 55.0%
zymase -> zymogenic common=zym old=1044695 new=469783 55.0%
zymogenic -> zymology common=zymo old=1044704 new=469789 55.0%
zymology -> zymolysis common=zymol old=1044714 new=469795 55.0%
zymolysis -> zymoplastic common=zymo old=1044726 new=469804 55.0%
zymoplastic -> zymoscope common=zymo old=1044736 new=469811 55.0%
zymoscope -> zymurgy common=zym old=1044744 new=469817 55.0%
zymurgy -> zyzzyva common=zy old=1044752 new=469824 55.0%
zyzzyva -> zyzzyvas common=zyzzyva old=1044761 new=469827 55.0%
http://en.wikipedia.org/wiki/Patricia_tree
我的模糊记忆告诉我,它们在一些早期的全文搜索引擎中被使用过...你在做什么?如果是拼写检查,可以使用布隆过滤器 - 参见这个代码练习。
你仍然需要使用 Trie 来维护树结构本身。 Huffman 编码 字母或 N 个字母(对于常见的形式,如“tion”、“un”、“ing”)可以利用字典中的出现频率并将条目压缩为位。
非常疯狂的想法...(即很可能是错误的)
将单词存储为所有可能字母组合的树,如何?
然后每个“单词”只需要一个字符和两个指针(一个指向字符,一个指向终止符),这样它们共享的字母越多,每个单词的成本就越低。
. .
/ /
r-p-s-.
/\\
a \s-.
/ t-.
c \
s-.
车 鲤鱼 鲤鱼们 汽车 手推车 购物车
因此,对于9个字符和14个指针,我们得到6个“单词”,总共25个字母。
搜索将很快(使用指针查找而不是字符比较),您可以进行一些词干优化以节省更多空间...?
编辑:看起来我重新发明了轮子。;-)
关于Paul的帖子:
你考虑过为什么不能在你的情况下使用Trie吗?如果只是一个实现问题,这里有一个紧凑的Patricia trie插入和搜索C代码实现(来自NIST):