我正在使用一种算法来索引已知的固定大小(例如64位或128位)的任意大的无符号整数。我希望能够将它应用于utf-8字符串,但为了做到这一点,我需要有一种可靠的方法将任意长度的给定字符串映射到这样一个固定大小的无符号字节数组。至少保留字符串前缀的词典顺序的方式。
这种天真的方法是简单地取字符串的第一个X
字符,并给每个字符一个完整的四个字节,根据需要在实际值前加零。但是,这将花费X * 4
个字节。我希望有一种方法可以做到更节省空间。
----编辑----
非常重要的是:碰撞是可以接受的。
使用上述天真的方法并给出字符串:
['Alabama', 'Alakazam', 'Alaska', 'Arkansas', 'Corduroy']
如果我们将X
设置为3,'Alabama','Alaska'和'Alakazam'会发生碰撞 - 只会从映射中产生三个唯一的12字节值(4字节 - 每个字符表示'Ala','Ark'和'Cor')。但是,这三个值保持其字典顺序非常重要。
我们必须使用4个字节,因为这是(我相信)单个字符在utf-8中可以占用的最大大小。为了保证我们的映射为我们提供了一个固定大小的字节数组(至少在这个方案中),我们必须有偶数ASCII字符,通常只占用一个字节,占用最多四个字节。
'A'=> 01100001,用零填充:00000000000000000000000001100001
'l'=> 01101100,用零填充:00000000000000000000000001101100
'a'=> 01100001,用零填充:00000000000000000000000001100001
因此,在X
= 4的示例中,以'Ala'开头的任何字符串都将映射到:
000000000000000000000000011000010000000000000000000000000110110000000000000000000000000001100001
当被视为96位无符号整数时,它的值将小于我们的示例('Ark'和'Cor')中其他前缀的映射值,因此可以满足保留映射的要求我们的词典排序。
此方案有效,但会将任何字符串的大小要求提高4倍。希望找到一个映射方案,用于完成少于X * 4
个字节的utf-8前缀索引。
答案 0 :(得分:1)
令人高兴的是,事实证明,UTF-8编码了字符串can be sorted lexicographically as-is。
排序顺序:前导字节的选择值和连续字节首先具有高位的事实意味着可以按代码点顺序对UTF-8字符串列表进行排序通过对相应的字节序列进行排序。
通过将字符串的字节序列截断为固定长度的前缀,您可以实现上述问题中描述的内容。