在保留排序的同时将文本转换为数字?

时间:2012-04-24 14:18:48

标签: string sorting language-agnostic

我有一个奇怪的要求,我似乎无法理解。我需要提出一个函数,它将获取一个文本字符串并返回一个对应于该字符串的数字 - 这样,在排序时,这些数字将与原始字符串的顺序相同。例如,如果我该函数产生了这个映射:

"abcd"  -> x
"abdef" -> y
"xyz"   -> z

那么数字必须是x < y < z。字符串可以是任意长度,但总是非空的,字符串比较应该不区分大小写(即"ABC""abc"应该产生相同的数值)。

我的第一个问题是将每个字母映射到相应的数字1到26,然后只得到结果数字,例如a = 1, b = 2, c = 3, ..., z = 26,然后"abc"将成为1*26^2 + 2*26 + 3,然而我意识到文本字符串可以包含任何语言的任何文本(即完整的unicode),因此这不起作用。此时我被困住了。在我告诉客户关闭之前还有其他想法吗?

P.S。这个奇怪的要求是由于专有系统的限制,只能通过数字字段进行排序。如果任何其他字段类型需要排序,则必须将其转换为某种数字表示 - 然后进行排序。不要问。

1 个答案:

答案 0 :(得分:0)

如果允许任意精度的实数,你可以使这个工作,虽然这有点像作弊。 Unicode字符串是从1,114,112个选项中提取的字符序列。因此,您可以将它们视为十进制基数-1,114,113数字:写入0,然后写出您的Unicode字符串,并且您在base-1,114,113中有一个实数(将每个字符的数值加1,以便缺少的字符具有该值0)。比较两个基数-1,114,113中的数字按字典顺序比较数字:如果你从左到右扫描数字,那么他们在两者之间的分歧上不同意的第一个数字。除非你有一个任意精度的实数库,否则这种方法是完全不可行的。

如果您只有IEEE-734双打,这种方法将无效。一种看待这种情况的方法是,如果你允许long double s,最多有2个 64 可能的双倍(或者2 80 )因为只有double中的64(80)位,但是有无数多个不同的字符串。这消除了这种可能性,仅仅是因为有太多的字符串可以使用。

不幸的是,如果你有任意精度的整数,你就无法做到这一点。字符串的自然顺序具有有趣的属性,您可以在它们之间找到字符串对,这些字符串在字典上有无限多个字符串。例如,请注意

  

a&lt; ab&lt; aab&lt; aaab&lt; aaaab&lt; ......&lt; B'/ P>

现在假设你有一个函数将每个字符串映射到一个遵循你喜欢的规则的整数。这意味着

  

f(a)&lt; f(ab)&lt; f(aab)&lt; f(aaab)&lt; f(aaaab)&lt; ......&lt; F(b)中

但这在整数中是不可能的 - 你不能有两个整数f(a)和f(b),它们之间有无穷多个整数。 (f(a)和f(b)之间的整数最多为f(b) - f(a) - 1)。

所以似乎答案是“如果你有任意精度的实数,这是可能的,用double s是不可能的,并且用任意精度整数是不可能的。”我基本上标注“在实践中不会发生”,即使它在理论上是可能的。 : - )