Java 使用递归将某个基数中的数字转换为十进制数

Java 使用递归将某个基数中的数字转换为十进制数,java,eclipse,recursion,Java,Eclipse,Recursion,我的任务是创建一个递归方法makeDecimal,当传递一个数字(由字符串表示)及其基数时,该方法将该数字转换为基数10。您需要使用方法Integer.parseInt(str)。(提示:使用子字符串。)此方法接受字符串并返回其整数形式 例如,Integer.parseInt(“21”)将返回整数21 以下是makeDecimal工作原理的一些示例: makeDecimal(“11”,2)将返回3 makeDecimal(“100”,4)将返回16 以下是我的尝试: public static

我的任务是创建一个递归方法makeDecimal,当传递一个数字(由字符串表示)及其基数时,该方法将该数字转换为基数10。您需要使用方法
Integer.parseInt(str)
。(提示:使用子字符串。)此方法接受
字符串并返回其整数形式

例如,
Integer.parseInt(“21”)将返回整数21

以下是makeDecimal工作原理的一些示例:

makeDecimal(“11”,2)
将返回3

makeDecimal(“100”,4)
将返回16

以下是我的尝试:

public static double makeDecimal(String number, int base){
    int len = number.length();
    double f = 0;

    if(len <= 0)
        return 0;
    else{
        makeDecimal(number,base);

        double temp = Integer.parseInt(number.substring(len - 1, len + 1));
        f = f + temp * Math.pow(3, len-1);
    }

    len--;
    return f;
}
publicstaticdoublemakedecimal(字符串编号,int-base){
int len=number.length();
双f=0;

如果(len您使用与传入的参数完全相同的参数进行递归。因此,调用本身将以相同的方式进行递归,直到堆栈溢出。这不是递归的工作方式。相反,您需要弄清楚如何在当前调用中处理一个问题,然后递归处理一个较小的问题

在您的代码中,甚至不清楚您使用的是什么逻辑。(计算3
len
-1有什么意义?)

  • 如果输入字符串的长度为0,则答案为0(正确的部分)
  • 否则,取最后一个数字并在当前基中对其进行解析。然后答案是该值加上
    base
    乘以所有值,直到但不包括输入的最后一个数字。(提示:这是使用递归的好地方。)
您应该能够将该描述转换为适当的方法调用和使用
substring()


哦,还有一件事:没有理由在这里使用
double
值。只需始终使用
int
变量。您将不需要
Math.pow()

编辑:起初,我不清楚递归对于这个解决方案是必须的,所以我没有它的原始答案可以在下面四个部分给出

这是一个带递归且不带
子字符串
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;
} 
public-double-makeDecimal(字符串值,int-base){
makeDecimal(value,base,value.length()-1);
}
公共双makeDecimal(字符串值、整数基、整数索引){
双结果=0;
如果(指数<0)
返回结果;
双字符值=0;
charcurrentchar=values.get(Character.toUpperCase(value.charAt(index));
如果(currentChar>=0&¤tChar='A'&¤tChar=base){
抛出新的InvalidValueException(“错误字符’+currentChar+”,对于base“'base+”””);
}
返回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;
}
private Map getCharValues(int-base)
{
映射值=新的HashMap();
for(int i=0;i

如果您需要大于36的基数,您可以在方法
getCharValues
中扩展字符集。另外,最好不要每次都创建
HasMap
,而是将其存储为最大基数,如果字符值超过给定的基数,则抛出异常。

在用Python编写原型之后,下面是我的解决方案(如果您感兴趣,我还可以提供Python源代码):

import java.util.HashMap;
导入java.util.Map;
公共类MakeDecimal{
公共静态最终地图字母表=buildalphabetable();
公共静态void main(字符串[]args){
//System.out.println(字母表);
System.out.println(makeDecimal(“af10bb1”,16));
}
//pos指字符在字符串中的位置。
//例如,如果您有以下二进制字符串100
//那么左边的1在位置2,
/中间的0位于位置1,
//最右边的0位于位置0
//(从右侧开始计数)。
//一般情况下,您可以通过以下方式转换该字符串:
// 2^2 * 1 + 2^1 * 0 + 2^0 * 0 = 4
//如果基数是n,那么你会
//第一个*n^{pos+”字符串长度-1}+…+倒数第二个*n^{pos+1}+最后一个*n^{pos}
//请注意,pos从0开始。
私有静态int-makeDecimal(字符串s、int-base、int-pos){
如果(s.length()==0){
返回0;
}否则{
int last=(int)Math.pow(base,pos)*alphabet.get(s.charAt(s.length()-1));
返回makeDecimal(s.substring(0,s.length()-1),base,pos+1)+last;
}
}
公共静态int-makeDecimal(字符串s,int-base){
如果(s.length()==0){
返回0;
}
如果(基底<2 | |基底>36){

抛出新的IllegalArgumentException(“not base>=2和base这里是使用递归、
子字符串和
整数的最简单解决方案。parseInt

public int makeDecimal(String value, int base) {
    // exit from recursion
    if (value.length() < 1) 
        return 0;

    //parsing last character of string
    int charValue = Integer.parseInt(value.substring(value.length() - 1), base);

    //calling recursion for string without last character
    return makeDecimal(value.substring(0, value.length() - 1), base) * base + charValue;
} 
public int makeDecimal(字符串值,int基){
//退出递归
if(value.length()<1)
返回0;
//解析字符串的最后一个字符
int charValue=Integer.parseInt(value.substring(value.length()-1),base);
//为不带最后一个字符的字符串调用递归
返回makeDecimal(value.substring(0,value.length()-1),base)*base+charValue;
} 
makeDecimal(nu
public int makeDecimal(String value, int base) {
    // exit from recursion
    if (value.length() < 1) 
        return 0;

    //parsing last character of string
    int charValue = Integer.parseInt(value.substring(value.length() - 1), base);

    //calling recursion for string without last character
    return makeDecimal(value.substring(0, value.length() - 1), base) * base + charValue;
}