Java递归常规疑问

时间:2011-02-07 18:56:23

标签: java recursion

我实现一个递归例程来计算多项式表达式的所有项,基本上是一个多项式扩展。我有点认为这会转化为以下几个问题 -

给定一组n个数值,其值范围为[0,1,2,... n],可以实现k的总和的最大组合数是多少。

以下是递归例程 -

public static String []multinomial_elements;
public static void multichoose(int n,int k)
{
    String[] result = null;
    System.out.print("Calling multichoose with");
    System.out.println("  "+Integer.toString(n)+"  "+Integer.toString(k));
    if(n==1)
    {
        multinomial_elements[result_iter]=multinomial_elements[result_iter]+Integer.toString(k)+"|";
        ++result_iter;
    }
    else
    {
        if(k==0)
        {
            result=new String[1];
            result[0]="0";
            for(int a=0;a<n;a++)
                multinomial_elements[result_iter]=multinomial_elements[result_iter]+"0"+"|";
            ++result_iter;   
        }
        else 
        {
            for(int firstindexval=k;firstindexval>=0;firstindexval--)
                for(int iter=0;iter<=k-firstindexval;iter++)
                {
                    if(iter+firstindexval==k){

                        multinomial_elements[result_iter]=multinomial_elements[result_iter]+Integer.toString(firstindexval)+"|";

                        multichoose(n-1,iter);
                    }

                }

        }
    }

}

multinomial_elements,如果数组在扩展的每个项目中都包含1个条目。上述代码背后的基本思想是,从第一项的最大可能值(功率),迭代到其最低可能值(功率),并通过这样做递归地在其他项上应用相同的逻辑。 从表示函数调用的print语句中,Im能够推断出我能够以正确的方式看到Im遍历树。然而输出似乎不稳定。我似乎搞乱了我在数组multinomial_terms中添加'firstindexval'的地方。这似乎发生在其中Im在处理较低节点之后返回到较高节点并因此程序不再具有'firstindexval'感的情况下。此推断基于以下输出 -

multichoose(3, 3);

3|0|0|
2|1|0|
0|1|
1|2|0|
1|1|
0|2|
0|3|0|
2|1|
1|2|
0|3|

关于我做错的任何指示或提示都会有很大的帮助。

由于 p1ng

1 个答案:

答案 0 :(得分:0)

您的例行程序的意图似乎是,总共k和术语总数n,以查找填充n项的所有排列值介于0和k之间。我假设这意味着对于案例n=3, k=3,你正在寻找

3|0|0|
2|0|1|
2|1|0|
1|0|2|
1|1|1|
1|2|0|
0|0|3|
0|1|2|
0|2|1|
0|3|0|

然而,你的代码有点杂乱无章。特别是,循环for(int iter=0;iter<=k-firstindexval;iter++)在其中包含if语句是完全不必要的,并且可以通过直接将递归调用中的k声明为k - firstindexval来替换。您的例程中与方法变量String[] result相关的所有代码似乎也完全没必要。

你的代码的主要问题是它返回void,并且递归调用不会传递当前的递归状态 - 换句话说,你没有直接或间接地使用堆栈,这使得它很难在遍历递归树时记住解决方案的当前状态。

例如,在2|1|0|之后的问题中,您的下一个结果是0|1|而不是正确的2|0|1|,因为递归不知道如何追加早期状态2|对于数组中的答案,即“堆栈状态”不会保留在生成的答案中。

让代码工作的一种快捷方法是向multichoose添加一个额外的String参数,其中包含递归的状态,如下所示。我添加到您的代码中的注释解释了这些更改。

public static void multichoose(int n,int k, String currentSolution /* NEW ARGUMENT */)
{
    // String[] result = null; /* UNNECESSARY */
    System.out.print("Calling multichoose with");
    System.out.println("  "+Integer.toString(n)+"  "+Integer.toString(k));
    if(n==1)
    {
        // multinomial_elements[result_iter]=multinomial_elements[result_iter]+Integer.toString(k)+"|";
        multinomial_elements[result_iter]=currentSolution+k+"|"; /* CHANGED */
        ++result_iter;
    }
    else
    {
        if(k==0)
        {
            // result=new String[1]; /* UNNECESSARY */
            // result[0]="0"; /* UNNECESSARY */
            for(int a=0;a<n;a++)
                // multinomial_elements[result_iter]=multinomial_elements[result_iter]+"0"+"|";
                currentSolution += "0|"; /* CHANGED */
            multinomial_elements[result_iter] = currentSolution; /* NEW */
            ++result_iter;   
        }
        else 
        {
            for(int firstindexval=k;firstindexval>=0;firstindexval--)
                //for(int iter=0;iter<=k-firstindexval;iter++) /* UNNECESSARY */ 
                //{ /* UNNECESSARY */
                    //if(iter+firstindexval==k){ /* UNNECESSARY */

                        //multinomial_elements[result_iter]=multinomial_elements[result_iter]+Integer.toString(firstindexval)+"|"; /* SEE CHANGE BELOW */

                        //multichoose(n-1,iter);
                        multichoose(n-1, k-firstindexval /* CHANGED */, currentSolution+firstindexval+"|" /* NEW ARGUMENT */); /* CHANGED */
                    //} /* UNNECESSARY */

                //} /* UNNECESSARY */

        }
    }

}

然而,可能有更好的方法来进行递归。