2013-11-01 3 views
1

Как преобразовать нечисловую строку в целое?Преобразование нечисловой строки в целое?

я получил, например:

String unique = "FUBAR";

Что хороший способ для представления строки в виде целого числа без каких-либо столкновений например «FUBAR» всегда должен быть представлен как одно и то же число и не должен сталкиваться с какой-либо другой строкой. Например, String a = "A"; должен быть представлен как Integer 1 и т. Д., Но что такое метод, который делает это (желательно для всех строк unicode, но в моем случае значения ASCII могут быть достаточными).

+1

er. это то, что делают кодировки символов. Получите байты строки, у вас есть число. – tom

+1

Какая цель у вас? Существует несколько способов преобразования строки в число и сохранения уникальности. Поскольку любые данные, в конце концов, хранятся как ряд бит, это скорее переинтерпретация, чем преобразование.Но если вы хотите, чтобы результат для любой строки любой длины соответствовал одному значению Java 'int', вы ищете хэш-функцию, которой много. Тем не менее, никогда не может быть идеального, гарантирующего отсутствие столкновений, так как существует более возможная последовательность, чем ints (принцип голубинки). –

+1

Я не могу придумать способ, который будет работать для * all * unicode-строк, независимо от того, как долго и преобразовать их в один 'int'. Но если вы найдете надежный способ, вернитесь и назовите свою цену: компании сжатия данных будут вас любить ;-) – dasblinkenlight

ответ

7

Это невозможно. Подумайте об этом, Integer может быть только 32 бит. Таким образом, по принципу «голубиная скважина» должны существовать как минимум две строки, которые имеют одинаковое значение Integer независимо от того, какую технику вы используете для преобразования. На самом деле, существуют бесконечные значения с одинаковыми значениями ...

Если вы просто ищете эффективное сопоставление, то я предлагаю вам просто использовать int, возвращенный hashCode(), который для справки фактически составляет 31 бит.

+0

OK, я тестирую это: 'new Integer (Integer.parseInt (" "+ this.getClass(). GetName(). HashCode() + id))' –

+3

Передано влево, потому что это возможно. Шестнадцатеричные числа содержат символы, и их можно легко преобразовать в 10 баз без каких-либо коллизий. – Torben

+2

@ 909Niklas какой ?? 'int idValue = (this.getClass(). getName() + id) .hashCode()' –

2

Если вы знаете, набор символов, используемый в ваших строках, то вы можете думать строки, как число с основанием, кроме 10. Например, шестнадцатеричные цифры содержат буквы от А до F.

Поэтому, если вы что ваши строки содержат только буквы из 8-битного набора символов, вы можете обрабатывать строку в виде 256-базового номера. В псевдокоде это будет:

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

Если набор символов содержит 65535 символов, а затем просто умножить «п» с этим номером на каждом шагу. Но будьте осторожны, 32 бита целого числа будут легко переполнены. Вероятно, вам нужно использовать тип, который может содержать большее число.

3

Вы можете сопоставить строки с уникальными идентификаторами, используя таблицу. Существует не способ сделать это в целом.

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; 
} 

Примечание: наличие уникального идентификатора не гарантирует никаких столкновений в коллекции хэшей.

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

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; 
} 
+0

Аналогичный код может быть выполнен с помощью BigInteger –

0

Может быть немного поздно, но я собираюсь дать мои 10 центов, чтобы упростить его (внутренне похож на BigDecimal предложил @Romain Hippeau)

public static BigInteger getNumberId(final String value) { 
    return new BigInteger(value.getBytes(Charset.availableCharsets().get("UTF-8"))); 
} 
1

Независимо от того, принятый ответ, можно представить любую String как Integer, вычислив Gedelnumber String, который является уникальным произведением простых чисел для каждой возможной String. С учетом сказанного это довольно непрактично и медленно реализуется, также для большинства строк вам понадобится BigInteger, а не нормальный Integer и для декодирования Gödelnumber в соответствующую строку String вам потребуется определенная Charset.

Смежные вопросы