我试图使用递归来实现硬币更改问题。我编写了以下代码,并面临静态类变量的问题。 '答案'是一个类变量,我试图在循环中添加返回值。这在while循环中工作正常,但在while循环结束后,答案重置为0;
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
以下是我编写的所有代码。您可以复制并运行它以进行检查。
import java.util.ArrayList;
import java.util.Collections;
public class CoinChangeHashMap {
static int answer = 0;
public static void main(String[] args) {
int[] array = new int[] { 7, 3, 2 };
ArrayList<Integer> input = new ArrayList<Integer>();
getList(array, input);
findCombinations(12, input);
System.out.println(answer);
}
private static void getList(int[] array, ArrayList<Integer> input) {
for (int i : array) {
input.add(i);
}
}
public static int findCombinations(int sum, ArrayList<Integer> denominations) {
if (denominations.size() == 1) {
if (sum % denominations.get(0) == 0) {
return 1;
}
return 0;
}
int i = 0;
int currentCoin = denominations.get(0);
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
return 0;
}}
**我得到的输出是0.但预期的输出是4.调试我得到的输出是**
inside while; answer is 0
inside while; answer is 0
inside while; answer is 1
inside while; answer is 1
inside while; answer is 2
inside while; answer is 2
inside while; answer is 0
inside while; answer is 0
inside while; answer is 0
0
感谢任何帮助。
答案 0 :(得分:0)
问题与您的奇怪代码结构有关,在这种结构中,您有时通过修改静态变量answer
来传达递归调用的结果,有时通过方法的返回值来传达。
如果你更仔细地分析问题,你会发现它不是在循环退出时部分结果丢失了,而是从方法返回后的一段时间。因此,请仔细考虑更新答案的方式:
answer = answer + findCombinations( /* ... */ );
在递归的最高级别,answer
最初为0
。当Java计算上面的表达式时,它首先计算左操作数,然后计算右操作数,然后添加它们。也就是说,它会在执行递归调用之前评估answer
,得到结果0
,。可以在递归调用过程中更新answer
的值,但这些更改来得太晚。只有递归的最底层才能返回一个不等于零的值,所以如果递归调用本身至少递归一个级别,那么它将返回零。在这种情况下,总和计算为0 + 0
,并分配给answer
,破坏方法执行的任何更新。
你可以通过交换总和中操作数的顺序来解决问题,但完全摆脱静态变量会更好,也不会更难。在方法中使用局部变量来累积结果,并且在所有情况下都通过方法的返回值将总数传回给调用者。