Модифицированный алгоритм 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.