【发布时间】:2020-04-19 22:07:25
【问题描述】:
我遇到的问题是,给定一个字节序列,我想确定它的最长前缀,假设 UTF8 编码,它形成一个有效的 Unicode 字符(扩展字形簇)。
我正在使用 Swift,所以我想使用 Swift 的内置函数来执行此操作。但这些函数只解码完整的字节序列。所以我想通过 Swift 转换字节序列的前缀,并采用最后一个没有失败且仅包含 1 个字符的前缀。显然,这可能会导致尝试整个字节序列,这是我想避免的。一个解决方案是在连续 4 个前缀失败后停止尝试前缀。如果我的问题中提出的属性成立,那么这将保证所有较长的前缀也必须失败。
我发现Unicode文本分割标准不可读,否则我会尝试直接实现扩展字素簇的边界检测...
【问题讨论】:
-
“实现扩展字素簇的边界检测。”哈哈你不想想那样做。那就是疯狂。老实说,使用
init?(validatingUTF8:)来检查逐渐变长的前缀并不是一个坏主意。虽然扩展的字形簇可能变得异常大(尝试将 this answer 复制到 unicode inspector 哈哈),但其中绝大多数都很小。 -
我绝对不想这样做 :-) 但这就是我问这个问题的原因!我希望我的代码即使在错误情况下也具有可预测的性能。
-
看起来完美的解决方案应该是像
findLongestValidCharacter(in input: [UnicodeScalar]) -> Character这样的函数。即使存在这样的功能,病态长字符仍然是一个问题。考虑到函数可能是O(input.count)而不是蛮力方法的O(input.count^2),“坏”的情况会不会那么糟糕,但这仍然会变得很糟糕。 -
您可以尝试深入研究标准库实现,看看它是如何破坏集群的:github.com/apple/swift/blob/…
-
我不太担心具有很长代码点序列的实际有效字符。如果发生这种情况,哦,好吧。但在我的场景中,字节序列很可能根本不是 UTF-8 字符串。如果那个字节序列是 80GB 长,我不想全部检查来发现它是无效的。