我有一个关于使用位向量方法的问题,该方法通常用于查找字符串是否具有唯一字符。我已经看到那些解决方案(one of them)适用于ASCII和UTF-16字符集。
然而,UTF-32的相同方法将如何运作?最长的连续位向量可以是Java中的长变量吗? UTF-16需要1024个这样的变量。如果我们采用相同的方法,它将需要2 ^ 26个长变量(我认为)。是否可以使用位向量来解决这么大的字符集?
答案 0 :(得分:3)
我认为你在这里缺少一些重要的东西。 UTF-32是Unicode的编码。 Unicode实际上适合21位空间。正如Unicode FAQ所述:
“Unicode标准编码U + 0000..U + 10FFFF范围内的字符,相当于21位代码空间。”
Unicode代码空间之外的任何UTF-32“字符”都是无效的......您应该永远不会以UTF-32编码String
查看它们。所以2 ^ 15长就足够了。
实际上,您不太可能在基本语言平面(平面0)之外看到代码点。因此,对于BMP使用位图(即代码高达65535)和使用其他窗格的稀疏数据结构(例如HashSet<Integer>
)是有意义的。
您还可以考虑使用BitSet
代替使用long
或long[]
“滚动您自己的”位设置数据结构。
最后,我不应该将您链接到的Q&amp; A中的某些代码用于寻找UTF-16中的唯一字符,原因如下:
使用类型为long
的N个变量和一个switch语句的想法无法扩展。 switch语句的代码变得庞大且难以管理......并且可能比JVM规范可以处理的更大。 (编译方法的最大大小是2 ^ 16 - 1字节的字节码,因此对于所有Unicode代码空间实现位向量显然是不可行的。)
最好使用一个long
数组,摆脱对switch
的需求...这只是因为你有N个不同的long
变量
在UTF-16中,每个代码单元(16位值)编码1个代码点(字符)或半个代码点。如果只是创建代码单元的位图,则不会正确检测唯一字符。
答案 1 :(得分:2)
嗯,long
包含64位信息,UTF-32字符集包含大约2 ^ 21个元素,这需要2 ^ 21位信息。如果UTF-32数据集使用了所有位,那么它将需要2 ^ 26个长变量。但是,实际上,您只需要2 ^ 13 long
个变量(仍然很多)。
如果您假设字符均匀分布在数据集上,则这种低效率是不可避免的,最好的解决方案是使用其他类似Set<Long>
之类的东西。但是,英文明文的大部分字符往往在ASCII范围内(0-127),并且大多数西方语言都被限制在特定范围内,因此您可以使用位向量来表示高频区域和{ {1}}或其他与订单无关的高效Set
数据结构,用于表示其他区域。