有效地存储相同单词的排列

时间:2014-10-12 19:07:55

标签: data-structures tree trie data-storage data-retrieval

我有一个与词典存储有关的问题。

我正在阅读关于Trie Data-structures的内容,到目前为止,我已经读过它作为前缀树工作得很好。但是,我来到Trie-DS,试图看它能否有效地减少通过同一个词形成的字母排列的存储。

例如:单词" ANT"," TAN"和NAT有相同的字母,但根据Trie,它继续为这些单词创建两个单独的路径。我可以理解Trie用于前缀存储并减少冗余。但是,任何人都可以帮助我减少冗余。 我想的一种方法是改变Trie的行为,因为每个节点都具有“完成”字样的状态。另外,如果我把“开始”字样放在'状态也是如此,我可以如下工作:

A
N - A - T
T - A - N

现在,每次我都可以检查这个单词是否从这里开始,直到结束。

这有意义吗?如果这是可行的? 或者他们是更好的方法吗?

由于

3 个答案:

答案 0 :(得分:1)

如果向每个节点添加一个状态字段,则会增加树的内存开销(假设8位字符)可能不是一个非常小的部分。

我知道您希望减少DS中的字母数量,但您必须考虑如果某些内容是其他内容的子集,例如,如何代表ANTAN。将最小数量的字符(128)视为完全连接图的节点。显然,所有单词都存储在此图表中,但不适合存储任何特定单词。没有办法说出单词结束的地方。存储在trie中的信息不仅仅是字母,而是完整且正确终止的单词。

如果您按照建议添加标记,您将如何编码:SUPERCHARGED,SUPER,PERCH。你可以在S和P设置word_starts,在R和H设置word_ends。你怎么知道不包含SUPERCH和PER?您可以改为使用非零标签并为单词的开头和结尾分配数字对:S:1 P:2 R:1 H:2。要确保开头和结尾可以出现在同一个字母上,您必须使用特定位作为标签。

然后你可以使用NATANT作为最小平面表示和N:001 A:000 T:011 A:100 N:010 T:100。在最坏的情况下,这需要#words位作为标记:A,AA,AAA ....如果你将它存储在树中,你将不得不寻找另一个标记,这不是树支持的操作。所以我看不到使用标记的好方法。

从信息理论的角度来看,我认为这里的关键问题是以一种独特的方式对一个单词的长度,顺序和内容进行适当的编码,以便对每种可能的组合进行编码。

我原本打算发表评论,但它有点冗长。我不确定这是否能回答你的问题,但我希望它有所帮助。

答案 1 :(得分:1)

您可以使用2次尝试并存储反向特里。然后你可以在搜索中的任何地方使用通配符扩展,例如你可以将搜索词分成两半,用前缀搜索一半,用后缀搜索另一半:http://phpir.com/tries-and-wildcards/。当您连接2时,您可以使用通配符进行有效搜索。

答案 2 :(得分:1)

你是否希望任何搜索" ant"也带来了" tan"和" nat"?

如果是这样,那么使用TrieMap,总是在读/写之前对键进行排序,并映射到该#34; anagram类中所有单词的容器。"

如果您只是在寻找减少使用Trie的空间开销的想法,那么请不要再犹豫了。我发现burst trie非常节省空间。我写了自己的burst trie in Scala,并重新使用了我在GWT's trie implementation中找到的一些想法。