编辑: 起初,我忽略了递归对于这个解决方案的必要性,所以我的原始答案没有它可能会比下面的方法多四个字符。
以下是使用递归且不使用
substring
和
Math.pow
的解决方案:
public double makeDecimal(String value, int base) {
makeDecimal(value, base, value.length() - 1);
}
public double makeDecimal(String value, int base, int index) {
double result = 0;
if (index < 0)
return result;
double charValue = 0;
char currentChar = values.get(Character.toUpperCase(value.charAt(index));
if (currentChar >= 0 && currentChar <= '9') {
charValue = currentChar - '0';
} else if (currentChar >= 'A' && currentChar <= 'Z') {
charValue = currentChar - 'A';
} else {
throw new InvalidValueException("Unsupported character '" + currentChar + "'.");
}
if (charValue >= base) {
throw new InvalidValueException("Wrong character '" + currentChar + "' for base '" base + "'.");
}
return makeDecimal(value, base, index - 1)) * base + charValue;
}
原始回答: 对于任何从2到36的进制,类似这样的代码都应该可以使用:
private Map<Character, Integer> getCharValues(int base)
{
Map<Character, Integer> values = new HashMap<Character, Integer>();
for (int i = 0; i < base; i++){
if (i < 10) {
values.put('0' + i, i);
} else if (i < 36) {
values.put('A' + i - 10, i);
} else {
throw new InvalidValueException("Base '" + base + "' not supported");
}
}
return values;
}
public double makeDecimal(String value, int base)
{
Map<Character, Integer> charValues = getCharValues(base);
double result = 0;
for (int i = 0; i < value.length(); i++){
result = result * base + charValues.get(Character.toUpperCase(Character.toUpperCase(value.charAt(i))));
}
return result;
}
如果您需要使用超过36个字符的基数,可以在方法
getCharValues
中扩展字符集。此外,最好不要每次创建
HasMap
,而只需将其存储到最大基数中,并在字符值超出给定基数时抛出异常。
makeDecimal(number,base);
- 这将使用与之前完全相同的参数进行递归调用,没有任何更改。这意味着它永远不会结束,因为它总是以相同状态进入方法。您需要确保在进行调用时传递不同的值。 - resueman