【问题标题】:Determine whether a UTF-32 encoded string has unique characters确定 UTF-32 编码的字符串是否具有唯一字符
【发布时间】:2015-05-17 08:30:41
【问题描述】:

我有一个关于使用位向量方法来查找字符串是否具有唯一字符的问题。我已经看到那些解决方案 (one of them) 适用于 ASCII 和 UTF-16 字符集。

但是,相同的方法如何适用于 UTF-32? Java中最长的连续位向量可以是长变量吗? UTF-16 需要 1024 个这样的变量。如果我们采用相同的方法,它将需要 2^26 个长变量(我认为)。这么大的字符集能用位向量解决吗?

【问题讨论】:

  • 这个问题是非常开放的;一些带有特定问题的代码会更好。我也不同意 utf-16 和 utf-32 需要不同数量的描述符/向量来完全描述 utf 字符集。
  • 在您的问题的上下文中,这些是否不同:aa 后跟 Unicode 组合“字符”分音符号,或 a 与分音符号(“aää”,即四个码点)?
  • @TomBlodget 是的。我不太清楚你所说的代码点是什么意思,但我实际上把这个问题想象成比较数字字节值。所以aä 本身并不相等。
  • 代码点是“字符”集的一个元素;一个可能有也可能没有与之关联的“字符”的数字。 Unicode 有一些称为“组合字符”的代码点。一个非组合码点后面可以跟任意数量的组合码点。它们一起形成了一个字形。不幸的是,Unicode 具有相同字素的多种表示形式:“ä”与“ä”。通过规范化,您可以将“ä”(U+00E4)转换为“ä”(U+0061 U+0308),但在与“a”(U+0061)进行比较时,您必须考虑到这一点。跨度>

标签: java string bitvector utf-32


【解决方案1】:

嗯,long 包含 64 位信息,而 UTF-32 字符集包含大约 2^21 个元素,这需要 2^21 位信息。如果 UTF-32 数据集使用所有位,则需要 2^26 个长变量是对的。但是,实际上,您只需要 2^13 个long 变量(仍然很多)。

如果您假设字符在数据集中均匀分布,则这种低效率是不可避免的,最好的解决方案是使用其他东西,如 Set<Long> 或其他东西。但是,英语纯文本的大部分字符往往在 ASCII 范围内 (0-127),并且大多数西方语言都相当受限于特定范围,因此您可以对高频区域使用位向量和 @ 987654324@ 或其他与顺序无关的高效contains 数据结构来表示其余区域。

【讨论】:

  • Unicode码位的数字空间为0x0到0x10FFFF,小于2^21。
【解决方案2】:

我认为你在这里遗漏了一些重要的东西。 UTF-32 是 Unicode 的编码。 Unicode 实际上适合 21 位空间。正如Unicode FAQ 所说:

“Unicode 标准对 U+0000..U+10FFFF 范围内的字符进行编码,相当于 21 位代码空间。”

Unicode 代码空间之外的任何 UTF-32“字符”都是无效的……您应该永远在 UTF-32 编码的String 中看到它们。所以 2^15 个 long 就足够了。

实际上,您不太可能在基本语言平面(平面 0)之外看到代码点。因此,对 BMP 使用位图(即最高 65535 的代码)和对其他窗格使用稀疏数据结构(例如 HashSet<Integer>)是有意义的。

您也可以考虑使用BitSet 代替使用longlong[] 的“滚动您自己的”位集数据结构。


最后,我不应该认为您链接到的问答中的某些代码不适合在 UTF-16 中查找唯一字符,原因如下:

  • 使用long 类型的N 个变量和switch 语句的想法无法扩展。 switch 语句的代码变得庞大且难以管理……并且可能超出 JVM 规范所能处理的范围。 (编译方法的最大大小是 2^16 - 1 个字节的字节码,因此对于所有 Unicode 代码空间实现位向量显然是不可行的。)

    使用long 的数组并摆脱对switch 的需要是一个更好的主意......这只是因为你有N 个不同的long 变量才真正存在。

  • 在 UTF-16 中,每个代码单元(16 位值)编码 1 个代码点(字符)或半个代码点。如果您只是创建代码单元的位图,您将无法正确检测到唯一字符。

【讨论】:

  • 同意。 W3 页面将 Unicode 描述为包含所有当前甚至古代语言字符的集合。所以我认为很多字符可能比 65535。但我喜欢你的 BMP 位图和其他人的 HashSet 的想法。
猜你喜欢
  • 2015-04-30
  • 1970-01-01
  • 2011-06-26
  • 2016-05-21
  • 2013-02-17
  • 1970-01-01
  • 2013-06-25
相关资源
最近更新 更多