解决此问题的常用方法是使用映射列表(通常列表不需要长于三个,在您的情况下两个就可以了。)每个映射将一个字符映射到一个序列点。[注 3] 所以在你的例子中,
primary: secondary:
A -> 0 A -> 0
Á -> 0 Á -> 1
B -> 1 (irrelevant)
C -> 2
D -> 3
E -> 4
...
T -> 20
U -> 21
V -> 22 V -> 0
W -> 22 W -> 1
X -> 23
...
比较算法本质上首先将单词中的每个字符转换为使用映射1,如果它们不相同,则将其用作比较。如果它们相同,则使用 mapping2 重复(依此类推)。
并非所有语言都如此简单,因此有很多变体(例如,您可能会在第 2 步中反转字符串)。
请注意,您可以通过制作由翻译连接组成的比较键来实现相同的效果。如果您进行大量比较,缓存此密钥可能是一个胜利。在这种情况下,您将在“无关”的第一个映射之外的映射中使用特殊值。所有不相关的代码都可以省略,这通常会大大缩短比较键。
例如,在您的示例中(但只是大写,因为键入整个映射序列会很乏味),我们将使用第一个映射到[22, 1, 20, 1, 15, 5, 15]
和第二个映射来翻译 VATANEN [0, 0, --, 0, --, --, --]
。WATANEN 将[22, 1, 20, 1, 15, 5, 15]
(完全相同)与第一个映射和[1, 0, --, 0, --, --, --]
第二个映射。因此删除--
's [注 1],比较键将是:
VATANEN: [22, 1, 20, 1, 15, 5, 15, 0, 0, 0]
VÁTANEN: [22, 1, 20, 1, 15, 5, 15, 0, 1, 0] (if there were such a place)
WATANEN: [22, 1, 20, 1, 15, 5, 15, 1, 0, 0]
VIRTANEN: [22, 9, ...]
这可以扩展到两个以上的转换表。
例如,许多应用程序想要执行不区分大小写的排序,但如果没有其他差异,则字符大小写会有所不同(在英语中,这通常意味着将带有大写字母的单词放在全部小写的单词之前,但两种选择都是合理的。)
所以在芬兰语的情况下,我们可以添加第三个翻译表,其中所有大写字母都被翻译为 0,所有小写字母都被翻译为 1,所有其他字符不被翻译。一些串联翻译:
-------primary--------- --2ary- ------tertiary-----
VÁTANEN: [22, 1, 20, 1, 15, 5, 15, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
Vátenen: [22, 1, 20, 1, 15, 5, 15, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1]
WATANEN: [22, 1, 20, 1, 15, 5, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
这个顺序是否“正确”一点也不明显。事实上,除了那些拥有官方语言权威的语言之外,对于大多数语言来说,“正确”意味着什么也不是很明显。[注 2] 因此,以上内容应仅视为多级编码的示例,而不是字母顺序的权威指南。在这种情况下,第三级代码仅由一个位组成,尽管可能仍有一些语言(如荷兰语)有几个字母的三种情况。
上面的方案没有考虑二合字母和三合字母,尽管它们很容易添加,但要小心。(在初级排序中,也可能在二级和三级排序中,二合字母需要为两个字符使用一个代码。)与非西班牙程序员的普遍看法相反,自 1994 年以来,西班牙语就不再是这样的例子,大约 20 年前,当 RAE 规定“ch”按字母顺序排列在“cg”和“ci”之间,而不是像以前那样在“c”和“d”之间。我相信一些讲荷兰语的人仍然希望同时找到“ij”和“y”,匈牙利人可能仍然尊重构成他们的字母表的复杂的二合字母和三合字母集合,但总的来说,用于字母排序的复杂机械方案正在消失,
[注1]:没有必要插入“不相关”的二级代码,因为编码的二级部分仅用于主要部分相同的单词对。由于任何被认为与二级编码无关的字母都会在一级等价类中的所有单词中被如此考虑,所以它可以从二级编码中省略。类似地,在不同的主要等价类中重用代码是合法的,就像我们上面所做的那样:[v, w] 是 [0, 1],[a, á] 也是。显然,没有歧义的可能性。因此,二次编码在序列长度和比特长度上都可能非常短。
[注2]:英语没有这样的主体;西班牙文是Real Academia Española,但我在书架上的任何 RAE 出版物中都找不到精确的校对规则,除了不按字母顺序考虑重音的简洁观察。然而,RAE 的字典似乎始终将不带重音的单词放在任何带有相同字母的重音单词之前,至少在我能想到的两种情况下——papa/papá 和 sabana/sábana。
[注 3] 当然,我们也需要跟踪原始数据,所以我们必须以某种方式将比较键附加到字符串。只要没有两个字符在所有映射中具有相同的翻译,这可以通过使用比较键作为键的简单哈希表来完成。