trie数据结构通常是一种用英语存储字符串的好方法。它的工作原理是构建一棵树,在树的每个边缘都用字母标记,并且到树中标记节点的路径会拼出数据结构中的单词之一。
该数据结构在英语中效果很好,因为英语字母中只有“ 26”个字母(“合理”的分支因子),这些字符具有连续的ASCII值(因此子指针可以存储在以索引为键的数组中) (每个孩子使用的字母),并且有很多带有共同前缀的英语单词(因此结构中存在很多冗余)。
我是母语为英语的母语人士,对其他语言和字母的了解有限,但似乎其中许多属性并不适用于其他语言。我知道,例如法语,西班牙语,德语和匈牙利语经常使用带重音符号的字符,这些字符不会与剩余的字母连续存储在Unicode空间中。希伯来语和阿拉伯语的元音标记通常在每个字母的上方或下方显示。中文使用徽标系统,韩文的韩文字符由三组较小的字符组成,它们组合在一起。
对于以这些语言和字母存储的数据,尝试仍然有效吗?尝试对此类数据进行哪些必要的更改(如果有)?是否有任何数据结构都能很好地适用于那些特别适合它们的语言和字母字符串,但在英语中却没有用或效率?
最佳答案
作为@JimMischel答案的附录,我想提出一个问题,即在其他语言中,通常有多种等效的方式来编写同一件事情。 Vietnamese(基于拉丁语/英语脚本)是一个很好的示例,其中常见的带有两个重音符号的字母。例如,从技术上讲,Ặ(U + 1EB6)也可以用Ă+点,Ạ+ breve,A + breve +点,A +点+ breve序列编写。
Unicode normalization可以通过将字符串转换为标准化的规范顺序来解决此问题。有4种不同的变体,NFC,NFKC,NFD和NFKD。我在这里不做过多介绍,但是前两个是“组合形式”,可以缩短字符串,将基本字符与其重音符号组合在一起,而后两个是“分解形式”,相反。
Hangul是一个有趣的情况:它是一个字母,尽管一个音节的所有字母都一起写在一个块中。单个字母和音节块都以Unicode形式存在。归一化可以解决这个问题,尽管不同音节的数量很大。使用NFC / NFKC可能不适用于trie,但在这种情况下,使用NFD / NFKD将音节分解为组成字母将是可行的。
需要考虑的其他一些无关的点:
除了已经提出的garçon/ garcon点之外,您还遇到了cote /coté/côte/côté问题,它们都是不同的法语单词。同样,希伯来语和阿拉伯语中的元音标记通常也不是必填项,这有时会引起歧义。
与英语相比,南亚和东南亚的字母1可以很大,大约是英文的两倍。
它们严格地称为abugidas,其中元音写为变音符号/重音符号,但是从编程的角度来看,通常可以忽略这种区别。