Модифицированный алгоритм base36 to base 10

Некоторое время назад я опубликовал вопрос об алгоритме, который генерирует 6-символьные строки base36 из целых чисел. У него есть ограничение: первый и последний символ всегда должны быть буквой, а вся строка - заглавной.

Вот алгоритм:

String getId(int id)
{
    String s = "";
    for(int i = 0; i < 6; i++)
    {
        int digit;
        if((i == 0) || (i == 5))
        {
            digit = (id % 26) + 10;         
            id /= 26;
        }
        else
        {
            digit = id % 36;
            id /= 36;
        }

        // add the digit to the string:
        if(digit < 10)
            s = (char)('0' + digit) + s;
        else
            s = (char)('A' + (digit - 10)) + s;
    }
    return s;
}

Я пытаюсь создать метод, который полностью изменяет это. Т.е. если дана строка, такая как A0000K, она вернет 10. Вот что у меня есть:

static int getNumber(String id) {
    int base = 36;
    int result = 0;
    int n = id.length();
    for (int i = 0; i < id.length(); i++)
    {
        n-=1;
        int digit = Character.digit(id.charAt(i), base);        

        if(i == 0 || i == 5) {
            result += digit * (Math.pow(base-10, n));
        }
        else {
            result += digit * (Math.pow(base, n));
        }

    }

    return result;
}

Я думаю, что проблема заключается в операторе if для вычисления результата, но я не слишком уверен, как его вычислить. Я основываю его на стандартных алгоритмах для преобразования из других баз в базу 10.

Кто-нибудь может помочь? Спасибо

2 ответа

Я бы сделал что-то вроде этого, используя предположение, что строка имеет длину 6 символов для упрощения:

static int getNumber(String id) {
    int sum = 0, val;
    char current;
    for(int i = 0; i < 6; i++) {
        current = id.charAt(i);
        val = ((int) current) - (int) 'A';
        if(val > 0){
            sum += (val + 10) * Math.pow(36,5-i);
        } else {
            sum += ((int) id.charAt(i)) * Math.pow(36,5-i);
        }
    }
    return sum;
}

Я не проверял это, но это должно работать, или, по крайней мере, быть довольно близко. Если вы продолжаете испытывать трудности, попробуйте пройти через это в отладчике.

Будет проще, если вы выполните итерацию от наименее значимого к наиболее значимому месту, отслеживая значение места каждой цифры / буквы.

Проверьте, является ли каждый символ цифрой или буквой, а затем конвертируйте в номинал. Цифры 0-9, буквы 10-35 за исключением 1-го и 6-го места, где они стоят на 10 меньше.

Умножьте номинал на место и прибавьте к результату. Увеличьте стоимость места, умножив на 26 или 36 в зависимости от позиции.

static int getNumber(String id) {
    int placevalue = 1;
    int result = 0;
    for (int i = id.length()-1; i >= 0; i--)
    {
        int facevalue;
        if(Character.isDigit(id.charAt(i)))
            facevalue = (int)id.charAt(i) - '0';
        else
            facevalue = ((int)id.charAt(i) - 'A') + 10;

        if(i == 0 || i == 5) {
            result += (facevalue - 10) * placevalue;
            placevalue *= 26;
        }
        else {
            result += facevalue * placevalue;
            placevalue *= 36;
        }
    }

    return result;
}

Выше не делает никакой проверки ввода. По крайней мере, вы должны проверить, что id.length равен 6.

Другие вопросы по тегам