6

如何将非数字字符串转换为整数?

例如,我得到:

String unique = "FUBAR";

将字符串表示为没有冲突的整数的好方法是什么,例如“FUBAR”应该始终表示为相同的数字并且不会与任何其他字符串发生冲突。例如,String a = "A";应该表示为 Integer1等等,但是这样做的方法是什么(最好适用于所有 unicode 字符串,但在我的情况下 ASCII 值可能就足够了)。

4

6 回答 6

9

这是不可能的。想想看,anInteger只能是 32 位。因此,根据鸽巢原理,Integer无论您使用什么技术进行转换,都必须至少存在两个具有相同值的字符串。实际上,有无限个具有相同值的...

如果您只是在寻找有效的映射,那么我建议您只使用int返回的 by hashCode(),它实际上是 31 位作为参考。

于 2013-11-01T10:27:31.650 回答
3

您可以使用表将字符串映射到唯一 ID。一般没有办法做到这一点。

final Map<String, Integer> map = new HashMap<>();
public int idFor(String s) {
    Integer id = map.get(s);
    if (id == null)
       map.put(s, id = map.size());
    return id;
}

注意:拥有唯一 id 并不能保证哈希集合中没有冲突。

http://vanillajava.blogspot.co.uk/2013/10/unique-hashcodes-is-not-enough-to-avoid.html

于 2013-11-01T10:42:26.047 回答
2

如果您知道字符串中使用的字符集,那么您可以将字符串视为基数不是 10 的数字。例如,十六进制数字包含从 A 到 F 的字母。

因此,如果您知道您的字符串仅包含来自 8 位字符集的字母,则可以将该字符串视为 256 基数。在伪代码中,这将是:

number n;
for each letter in string
    n = 256 * n + (letter's position in character set)

如果您的字符集包含 65535 个字符,则只需在每个步骤中将“n”乘以该数字。但请注意,整数的 32 位很容易溢出。您可能需要使用可以容纳更大数字的类型。

于 2013-11-01T10:32:12.530 回答
1
private BigDecimal createBigDecimalFromString(String data)
{
    BigDecimal value = BigDecimal.ZERO;

    try
    {
        byte[] tmp = data.getBytes("UTF-8");
        int numBytes = tmp.length;
        for(int i = numBytes - 1; i >= 0; i--)
        {
            BigDecimal exponent = new BigDecimal(256).pow(i);
            value = value.add(exponent.multiply(new BigDecimal(tmp[i])));
        }
    }
    catch (UnsupportedEncodingException e)
    {
    }
    return value;
}
于 2016-06-27T18:37:19.633 回答
1

也许有点晚了,但我会花 10 美分来简化它(内部类似于@Romain Hippeau建议的 BigDecimal )

public static BigInteger getNumberId(final String value) {
    return new BigInteger(value.getBytes(Charset.availableCharsets().get("UTF-8")));
}
于 2017-02-08T23:00:54.540 回答
1

无论接受的答案如何,都可以通过计算字符串的哥德尔数来将任何字符串表示为整数,这是每个可能字符串的素数的唯一乘积。话虽如此,实现起来非常不切实际且缓慢,同样对于大多数字符串,您需要一个 BigInteger 而不是普通的 Integer,并且要将 Gödelnumber 解码为其相应的字符串,您需要定义一个字符集。

于 2017-12-18T20:07:45.247 回答