0

我想使用 Redis 对字符串值进行排序(使用排序集),但我只能为此目的使用浮点数。我正在寻找一种算法来将字符串转换为浮点 0..1 值,同时保持顺序。

我的意思是 s1 < s2(按字母顺序)应该意味着 f(s1) < f(s2)。

有这样的算法吗?

PS我将使用这样的算法对用户名进行排序,在大多数情况下,得分匹配的玩家会有完全不同的用户名。所以在大多数情况下,任何一种方法都应该有效,但仍有碰撞的空间。另一方面,字符串将被正确排序,如果几乎相同的用户名排序不正确,这是可以接受的。

4

2 回答 2

3

每个字符都可以映射到其ASCII编号。如果您将每个字符串转换为连接所有 ASCII 数字的等效浮点数(最后在它们前面加上零,以便所有字符都映射到三个数字),您将继续排序。但是如果你的字符串很长,你的浮点数会很大并且你的映射可能不是唯一的(如果几个字符串以相同的字符开头,由于浮点数内部的舍入)。

例如:

'hello' -> 104101108108111

如果您知道您的字符串包含哪些字符子集(例如,只有小写字母,或者只有大写字母和数字),您可以创建自己的映射以减少每个字符的数字。

于 2013-03-06T13:13:58.297 回答
1

从数学上讲,这样的算法存在并且很简单:只需在字符串前面放一个小数点(“.”)并将其解释为 base-256 数字(假设您的字符串使用 8 位字符)。类似地,如果您的字符串只有字符“0”到“9”,您会将其读取为十进制数字,例如字符串“58229”的 .58229。您正在做同样的事情,只是使用基数 256 而不是基数 10。

实际上,如果没有一组严格限制的潜在字符串或特殊的浮点软件,这是不可能的。由于典型的浮点对象具有有限大小,因此它具有有限数量的可能值。例如,一个 64 位的浮点对象最多有 2个 64值,甚至忽略那些代表特殊概念(如 NaN)的值。相反,任意长度的字符串具有无限多个潜在值。即使您将字符串限制在当今计算机内存中合理的范围内,它也具有比普通浮点对象更多的潜在值。

要解决此问题,您必须减少潜在字符串的数量(通过限制其长度或以其他方式限制允许的字符串)或增加潜在浮点值的数量(可能通过使用特殊的任意精度浮点软件)。

于 2013-03-06T14:00:36.277 回答