Unicode字符串的高效Trie实现


12

我一直在寻找有效的String trie实现。通常,我发现这样的代码:

Java中的引用实现(每个维基百科)

我不喜欢这些实现主要有两个原因:

  1. 它们仅支持256个ASCII字符。我需要介绍西里尔字母。
  2. 它们的内存效率极低。

每个节点包含256个引用的数组,在Java的64位计算机上为4096字节。这些节点中的每个节点最多可以具有256个子节点,每个子节点具有4096字节的引用。因此,每个ASCII 2字符串的完整Trie要求超过1MB。三个字符串?256MB仅用于节点中的阵列。等等。

当然,我不打算在Trie中使用全部1600万个三个字符串,因此浪费了很多空间。这些数组中的大多数只是空引用,因为它们的容量远远超过了插入键的实际数量。而且,如果我添加unicode,数组会更大(char具有64k值,而不是Java中的256)。

有没有希望对字符串进行有效的尝试?我考虑了对这些类型的实现的一些改进:

  • 除了使用引用数组之外,我还可以使用原始整数类型的数组,该数组将对大小与实际节点数接近的节点的引用数组进行索引。
  • 我可以将字符串分成4位部分,这将允许以更大的树为代价允许大小为16的节点数组。

Answers:


2

您正在使用这个trie做什么?您计划保留的单词总数是多少,其组成字符的稀疏程度是什么?最重要的是,特里树是否更合适(相对于前缀到单词列表的简单映射)?

只要您拥有相对较少的短单词集和稀疏字符集,就可以使用中间表并用索引替换指针的想法。否则,您可能会面临中间表空间不足的风险。而且,除非您查看的是极少的单词集,否则您实际上不会节省那么多的空间:32位计算机上的简短引用为2个字节,而引用为4个字节。如果您在64位JVM上运行,则节省的费用会更多。

将字符分成4位块的想法可能不会为您节省很多,除非所有期望的字符都在非常有限的范围内(对于限于大写US-ASCII的单词来说可能是可以的,对于一般的Unicode语料库则不太可能) )。

如果您的字符集稀疏,那么a HashMap<Character,Map<...>>可能是最佳的实现。是的,每个条目都会更大,但是如果您没有很多条目,您将获得总体胜利。(作为旁注:我一直以为Tries上的Wikipedia文章显示了-也许仍然如此-基于散列数据结构的示例,完全忽略了该选择的时空折衷,这很有趣)

最后,您可能希望完全避免尝试。如果您正在查看人类语言中的一组普通单词(正在使用的10,000个单词,长度为4-8个字符的单词),则最好使用a HashMap<String,List<String>作为键,键是整个前缀。


-引用在32位计算机上为8字节,在64位计算机上为16字节-用于自动完成功能-字符串中的大多数字符都在ASCII范围内,但是抛出了一些中欧字符。这就是为什么我想要较小的分支大于256,因为它将切出大量字符。我看不到HashMap <String,List <String >>是更好或更快速还是更少的内存消耗,尽管确实很容易编写和使用。但是我会接受HashMap <Character,Map>的想法。超过128个字符就可以了(在我的情况下很少见-对中文文本不利)。
RokL 2012年

4

如果您将字符串编码为UTF8,则可以使用标准的256个分支特里树,并且仍兼容unicode

您还应注意,在可能进行优化的128个ascii字符(均以UTF8编码为1个字节)中,只有70个左右的字符可以找到,您可以对此进行优化(例如,用常用的有向图代替未使用的控制字符) )


我知道UTF8可以这样表示。但是,这仍然不能解决仍然很高的内存消耗。将字符交换到基本256范围内将需要很多转换语句,我怀疑这样做是否值得。就UTF-8而言...这实际上是我现在正在考虑的问题。Java String使用UTF-16字符,我可以很容易地得到它,我可以逐字节编码这些字符。或者,我可以转换为UTF-8并使用它。在这一点上,我尚不清楚从UTF-16转换为UTF-8的成本是否高得惊人。
RokL 2012年

您大多数时候使用的语言是什么?尝试针对所有事物进行优化是不可能的(或者已经完成),因此针对常见情况进行优化
棘手怪胎2012年

1
这是少数几个使用CESU-8优于UTF-8的用例之一:在这里最大的优点是,从UTF-8代码点转换为相应的CESU-8代码点是微不足道的(而您需要解码1-2个UTF-16码点以获得相应的UTF-8码点)。
约阿希姆·绍尔

1
@ratchetfreak Java。尽管我认为这个问题可以推广到大多数语言。我猜在C语言中,您可以简单地将指针转换byte*为按位特里编码任何类型。
RokL 2012年

@UMad我的意思是输入字符串将使用哪种语言(英语,法语,德语,...)
棘手怪胎2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.