我实现一个递归例程来计算多项式表达式的所有项,基本上是一个多项式扩展。我有点认为这会转化为以下几个问题 -
给定一组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
答案 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 */
}
}
}
然而,可能有更好的方法来进行递归。