【问题标题】:Efficient lookup table for unicode code points用于 unicode 代码点的高效查找表
【发布时间】:2018-06-21 05:46:27
【问题描述】:
想知道 unicode 代码点查找表是如何完成的。也就是说,给定一个字符,如a,返回U+24B6,反之亦然。想知道是否有任何有效的技巧,使其不仅仅归结为:
a: U+24B6
b: ...
c: ...
这会占用大量文件大小(和内存)。也许有一种紧凑的方式可以在文件中表示它(不确定this 是否正在这样做),然后在运行时将其扩展到更大的内存。
for x in y:
map[x | something] = U + x + 123
或者也许有一种方法可以在运行时保持最小化,所以它是动态计算的。
【问题讨论】:
标签:
optimization
data-structures
unicode
encoding
codepoint
【解决方案1】:
首先,如果您想将一个代码点映射到另一个代码点,那么绝对不需要映射到像U + x + value 这样的字符串。只需将代码点直接存储在从 char 到 char 的映射中(char 是一种足以存储所有 Unicode 代码点的类型,例如 C++ 中的 std::unordered_map<int32_t, int32_t>)
map['a'] = 0x24B6;
map['x'] = 123;
看起来在上面的 iconv-lite 存储库中,代码点存储为像“8140”这样的字符串,效率非常低
但这仍然过于宽泛,因为它实际上取决于您要映射的内容。不同的映射有不同的方法来散列输入值(除非您想使用内存效率更高但速度更慢的排序字典)。但是如果你想将a映射到Ⓐ,b映射到Ⓑ,c映射到Ⓒ……那么线性转换就足够了。这是一个伪函数示例,它将 A-Z 映射到 ⓐ-ⓩ (0x24D0-0x24E9),a-z 映射到 Enclosed Alphanumerics block 中的 Ⓐ-Ⓩ (0x24B6-0x24CF) 和 0- 9 到 ?-? (0x1F101-0x1F10A)
func map(char input)
if 'a' <= input && input <= 'z':
return input - 'a' + 'Ⓐ'
if 'A' <= input && input <= 'Z':
return input - 'a' + 'ⓐ'
if '0' <= input && input <= '9':
return input - '0' + '?'
return '\0';
不需要查找表