【问题标题】:String to Number and back algorithm字符串到数字和返回算法
【发布时间】:2010-10-05 13:43:03
【问题描述】:

这对我来说很难,我希望人们可以帮助我。我有一些文本,我需要将其传输到一个号码,但它必须是唯一的,就像文本是唯一的一样。

例如: 单词“kitty”可以产生 12432,但只有单词 kitty 产生这个数字。文本可以是任何内容,并且应该给出适当的数字。

有一个问题,结果整数必须是 32 位无符号整数,这意味着可能的最大数字是 2147483647。我不介意是否有文本长度限制,但我希望它可以尽可能大。


我的尝试。您有字母 A-Z 和 0-9,因此一个字符可以有 1-36 之间的数字。但是如果 A = 1 和 B = 2 并且文本是 A(1)B(2) 并且你添加它你会得到 3 的结果,问题是文本 BA 产生相同的结果,所以这个算法不会工作。

有什么想法可以为我指明正确的方向还是不可能做到?

【问题讨论】:

  • 所以,你想要一个perfect hash function...
  • @KennyTM - 我也可以拥有一个吗!
  • 首先感谢大家的好回复!其次,我想指定文本仅是大写字母,并且有数字,所以 A-Z 和 0-9 总共是 36 个字符。所以你可以有 MARK 或 KRISS,这些应该变成数字。我只希望我能找到一种可以处理大约 12 个字符长的文本的方法,但我想现在 6 似乎是最大值。我还没有查看每一个回复,但我会在足球训练后这样做。

标签: algorithm string numbers formula


【解决方案1】:

你的想法大体上是理智的,只需要稍微发展一下。

f(c) 是一个函数,将字符c 转换为[0..M-1] 范围内的唯一数字。然后你可以像这样计算整个字符串的结果数。

f(s[0]) + f(s[1])*M + f(s[2])*M^2 + ... + f(s[n])*M^n

您可以轻松证明特定字符串的数字是唯一的(并且您可以从数字中获取字符串)。

显然,您不能在此处使用很长的字符串(您的情况最多为 6 个字符),因为 36^n 增长很快。

【讨论】:

  • 啊,这是对我输入的内容的更正式的定义。 +1
  • @kriss 我从问题中得到了范围:Mark想要数字和字母。
  • 你能分享一下如何从号码中取回字符串吗?
【解决方案2】:

假设您试图将字符集“0-9”中的字符串仅存储在一个数字中(相当于获取一个数字字符串的数字)。你会怎么做?

Char 9 8 7 6 5 4 3 2 1 0
Str  0 5 2 1 2 5 4 1 2 6

Num = 6 * 10^0 + 2 * 10^1 + 1 * 10^2...

对你的角色应用同样的东西。

Char 5 4 3 2 1 0 
Str  A B C D E F
L = 36

C(I): transforms character to number: C(0)=0, C(A)=10, C(B)=11, ...

Num = C(F) * L ^ 0 + C(E) * L ^ 1 + ...

【讨论】:

  • 几点注意事项:这是可逆的,我认为这是您的要求,因为您想防止碰撞,其次,您不需要像我一样按倒序进行;我只是使用降序索引来演示与atoi 类型函数的相似性。
【解决方案3】:

用映射到唯一数字的单词构建字典并使用它,这是你能做的最好的事情。

我怀疑使用的单词数量超过 2^32,但这不是您面临的问题,问题是您需要将数字映射回单词。

如果您只是将单词映射到数字,则某些哈希算法可能会起作用,尽管您必须做一些工作以保证您拥有一个不会产生冲突的算法。

但是,对于数字回到单词,这是一个完全不同的问题,最简单的解决方案是构建一个字典并映射两种方式。

换句话说:

AARDUANI = 0
AARDVARK = 1
...

如果您想将数字映射到以 26 个字符为基数,则只能存储 6 个字符(如果我计算错误,则只能存储 5 或 7 个),但不能存储 12,当然也不能存储 20。

除非您只计算实际单词,并且它们不遵循任何好的可数规则。唯一的办法就是把所有的单词放在一个长长的列表中,然后从头开始分配数字。

【讨论】:

    【解决方案4】:

    如果某些语言的文本拼写正确,则可以为每个单词指定一个数字。但是,您需要考虑所有可能的复数形式、地名和人名等,这通常是不可能的。我们在谈论什么样的文本?通常会有一些现有的单词在没有事先了解的情况下无法以任何方式编码为 32 位。

    你可以建立一个单词列表吗?只需给你看到的第一个单词 1,第二个数字 2 并检查一个单词是否已经有一个数字,或者它是否需要一个新的。然后将新创建的字典保存在某处。如果您需要 100% 可靠、可逆地从数字到原始单词的映射,这可能是唯一可行的解​​决方案,因为新的未知文本不遵循任何已知模式。

    对于 64 位和足够好的哈希(如 MD5),它极不可能发生冲突,但对于 32 位,似乎不太可能存在安全哈希。

    【讨论】:

      【解决方案5】:

      只要把每个字符都当作一个以 36 为底的数字,然后计算十进制等值?

      所以:

      'A' = 0
      'B' = 1
      [...]
      'Z' = 25
      '0' = 26
      [...]
      '9' = 35
      'AA' = 36
      'AB' = 37
      [...]
      'CAB' = 46657
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-25
        • 2021-04-26
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多