为什么这个递归算法错了?

时间:2013-05-01 11:20:01

标签: java algorithm recursion

我用Java编写的这个方法有问题。

该方法是采用两个字符串。第一个字符串sArr用于跟踪在解析第二个字符串时添加的字母。第二个字符串str是一个整数字符串,其中每个整数按顺序用于添加到sArr。 每个整数引用不同的字母数组,例如:

 String[] two = {"A", "B", "C"};

目前它是另一种辅助方法。 如果我输入任何内容,它将只使用输入的第一个数字。它应该从数字输出集合的所有排列。因此输入22将输出:AA, AB, AC, BA, BB, BC, CA, CB, CC

我一直在使用的测试输入是printStrAux("", 23); 后续输出是2集合中的所有字母,如下所示:ABC

我不一定想成为勺子答案,但任何帮助都会很精彩。

public static void printStrings(String str){
    if(isAllDigits(str))
        System.out.println(printStrAux("", str));
}

protected static String printStrAux(String sArr, String str){
    if(str.equals(""))
        return sArr;


    else{

        Integer val = Integer.parseInt(str.substring(0, 1));

        switch (val) {
        case 1: printStrAux(sArr, str.substring(1));
        break;
        case 2: 
            for(int i = 0; i < two.length; i++){
                printStrAux(sArr += two[i], str.substring(1));
            }

        break;
        case 3: 
            for(int i = 0; i < three.length; i++){
                printStrAux(sArr += three[i], str.substring(1));
            }

        break;

        case 4:  
            for(int i = 0; i < four.length; i++){
                printStrAux(sArr += four[i], str.substring(1));
            }

        break;
        case 5:  
            for(int i = 0; i < five.length; i++){
                printStrAux(sArr += five[i], str.substring(1));
            }

        break;
        case 6:  
            for(int i = 0; i < six.length; i++){
                printStrAux(sArr += six[i], str.substring(1));
            }

        break;
        case 7:  
            for(int i = 0; i < seven.length; i++){
                printStrAux(sArr += seven[i], str.substring(1));
            }

        break;
        case 8:  
            for(int i = 0; i < eight.length; i++){
                printStrAux(sArr += eight[i], str.substring(1));
            }

        break;
        case 9:  
            for(int i = 0; i < nine.length; i++){
                printStrAux(sArr += nine[i], str.substring(1));

        }
        break;
        case 0:  {
            printStrAux(sArr, str.substring(1));
        }
        break;


        }

    }
    return sArr;
}

请记住,我几乎不知道我在这里做什么而不是我想要的。

3 个答案:

答案 0 :(得分:2)

退一步思考递归的基本原理。如果你除了空列表列表以“2”开头之外的所有情况可能会有所帮助。稍后将案例放入其他数字。

像这样的收集递归函数的模式是:

private Type func(Type accumulator, List input) {
    if(input.size() == 0) {
        return accumulator;
    } else {
        Type myAccumulated = someOperation(accumulator, input.head());
        return func(myAccumulated, input.tail();
    }
}

(我假设List.head()和List.tail()存在,为简洁起见。你用substring()实现了这些。

在您的情况下,Type是String,您使用String作为字符列表。

努力调整这种一般模式。你没有做的一件基本事情就是将递归调用的输出捕获到func()并将其合并到你返回给调用者的内容中。


除了递归:

  • 考虑将您的Type数据结构设为List&lt; List&lt; Char&gt;&gt;而不是一个字符串。它可能更容易推理,你可以编写另一种方法将其转换为String。
  • 不是拥有名为twothree等的变量,而是拥有一系列序列。 sequences[2] = {"A","B","C"}。然后,您将不需要一堆几乎相同的case块。

答案 1 :(得分:1)

在对printStrAux的递归调用中,不保留返回值sArr。

答案 2 :(得分:1)

当你递归调用你的方法时,你需要捕获它的返回值,例如:

sArr = printStrAux(sArr += two[i], str.substring(1));