【问题标题】:Convert text to numbers while preserving ordering?在保留顺序的同时将文本转换为数字?
【发布时间】:2012-05-05 04:55:35
【问题描述】:

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

"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),所以这是行不通的。在这一点上,我被困住了。在我告诉客户草皮之前还有其他想法吗?

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

【问题讨论】:

  • 你能在应用程序之外进行排序吗?即做一个正常的阿尔法排序,那么你的映射只是排序列表中的索引?
  • @TonyHopkinson 如果数据不是来自应用程序本身,这将是一个选项。
  • 允许什么样的数字?你能做任意精度的实数或分数吗?
  • @templatetypedef 我想是的。这是 5 年前的事了,我什至不记得那个项目是什么了 :)
  • 哈哈哈,谢谢。我只是偶然发现了这个问题,并认为它真的很有趣。 :-)

标签: string sorting language-agnostic


【解决方案1】:

如果你允许任意精度的实数,你就可以做到这一点,尽管这有点像作弊。 Unicode 字符串是从 1,114,112 个选项中提取的字符序列。因此,您可以将它们视为以 1,114,113 为底的十进制数字:写 0.,然后写出您的 Unicode 字符串,然后您就有一个以 1,114,113 为底的实数(将每个字符的数值上移 1,以便缺失的字符具有值0)。在 base-1,114,113 中比较这些数字中的两个数字会按字典顺序比较数字:如果您从左到右扫描数字,则在两者之间的抢七中他们不同意的第一个数字。除非您有任意精度的实数库,否则这种方法是完全不可行的。

如果您只有 IEEE-734 双打,这种方法将行不通。看到这一点的一种方法是最多有 264 个可能的双打(如果您允许 long doubles,则最多有 280 个),因为只有 64 个 ( double 中有 80) 位,但有无限多不同的字符串。这消除了这种可能性,仅仅是因为有太多的字符串要绕过。

不幸的是,如果您有任意精度的整数,您将无法完成这项工作。字符串的自然排序具有有趣的特性,您可以找到在它们之间按字典顺序具有无限多个字符串的字符串对。例如,请注意

a

现在假设您有一个函数,可以将每个字符串映射到一个符合您想要的规则的整数。这意味着

f(a)

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

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

【讨论】:

  • 这是真的——但前提是你坚持使用整数。我的问题中没有说“整数”,只说“数字”。然后 0.1 > 0.01 > 0.001 > ... > 0
  • @AleksG 哦,哎呀,我完全看错了。让我考虑一下……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
  • 2015-10-14
  • 2014-07-20
  • 2015-03-11
  • 2021-08-31
  • 1970-01-01
  • 2019-05-30
相关资源
最近更新 更多