Короткий уникальный идентификатор - PullRequest
2 голосов
/ 26 сентября 2011

Я создаю инструмент для оптимизации скрипта, и теперь я хочу сжать все имена в нем до минимума. Я запустил функцию для нее, но она как-то глючит и останавливается после превышения длины 2. Есть ли более простой способ сделать это? Мне просто нужен шаблон, который генерирует строку, начинающуюся с a -> z, затем aa -> az ba -> bz и т. Д.

    public String getToken() {
    String result = ""; int i = 0;
    while(i < length){
        result = result + charmap.substring(positions[i], positions[i]+1);
        positions[length]++;
        if (positions[current] >= charmap.length()){
            positions[current] = 0;
            if ( current < 1 ) {
                current++;length++;
            }else{
                int i2 = current-1;
                while( i2 > -1 ){
                    positions[i2]++;
                    if(positions[i2] < charmap.length()){
                        break;
                    }else if( i2 > 0 ){
                        positions[i2] = 0;
                    }else{
                        positions[i2] = 0;
                        length++;current++;
                    }
                    i2--;

                }


            }


        }
        i++;
    }
    return result;
}

НРАВИТСЯ С ДРУГИМИ ВОПРОСАМИ !! Я не хочу просто увеличивать целое число, длина увеличивается до много.

Ответы [ 7 ]

1 голос
/ 26 сентября 2011

Вот тот, который я использовал

public class AsciiID {
    private static final String alphabet= 
                   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private int currentId;

    public String nextId() {
        int id = currentId++;
        StringBuilder b = new StringBuilder();
        do {
            b.append(alphabet.charAt(id % alphabet.length()));
        } while((id /=alphabet.length()) != 0);

        return b.toString();
    }
}
1 голос
/ 26 сентября 2011

Я бы использовал библиотеку base 36 или base 64 (в зависимости от чувствительности к регистру) и запускал ее с целым числом, а перед выводом преобразовал бы целое число в число 36/64.Вы можете думать с точки зрения последовательности, что проще, и выходное значение обрабатывается доверенной библиотекой.

0 голосов
/ 19 января 2017

Эта функция генерирует N-ное Биективное число (кроме нуля).Это самое оптимальное кодирование из всех возможных.(Ноль будет пустой строкой.)

Если бы было 10 возможных символов, 0 - 9, он генерирует в порядке:

  • 10 строк длины 1 , от "0" до "9"
  • 10 * 10 строк длиной 2 , от "00" до "99"
  • 10 * 10 * 10 строк длиной 3 , от "000" до "999"
  • и т. Д.

В примере используется 93 символа, потому что я простоСлучилось так, что они нужны для Джсона.

0 голосов
/ 26 сентября 2011

В вашем инструменте вам нужно создать словарь, который будет содержать уникальный целочисленный идентификатор для каждой уникальной строки и самой строки.При добавлении строк в словарь вы увеличиваете заданный идентификатор для каждой вновь добавленной уникальной строки.Как только словарь заполнен, вы можете просто конвертировать идентификаторы в String, используя что-то вроде этого:

  static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  static final int CHARS_LENGTH = CHARS.length();

  public String convert(int id) {
    StringBuilder sb = new StringBuilder();
    do {
      sb.append(CHARS.charAt(id % CHARS_LENGTH));
      id = id / CHARS_LENGTH;
    } while(id != 0);
    return sb.toString();
  }    
0 голосов
/ 26 сентября 2011

Хорошо, давайте предположим, что мы можем выводить только ASCII (для юникода эта проблема становится ... сложной): как видно из бегства, его печатаемые символы находятся в диапазоне [32,126].Таким образом, чтобы получить наиболее эффективное представление этой проблемы, мы должны, так сказать, кодировать данное целое число в базе 94 и добавить 32 к любому сгенерированному символу.

Как вы это делаете?Посмотрите, как Sun делает это в Integer.toString() и адаптируйте его соответствующим образом.Ну, это, вероятно, сложнее, чем необходимо - просто подумайте, как вы конвертируете число в основание 2 и адаптируете его.В простейшей форме это в основном цикл с одним делением и модулем.

0 голосов
/ 26 сентября 2011

Вы можете использовать:

Integer.toString(i++, Character.MAX_RADIX)

Это base36.Он будет сжат не так сильно, как Base64, но у вас есть однострочная реализация.

0 голосов
/ 26 сентября 2011

Вы можете найти библиотеку, которая оперирует числами с любым основанием, скажем, 27, 37 или более.Затем вы выводите это число в виде буквенно-цифровой строки (например, HEX, но с a-zA-Z0-9).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...