将值从内部递归方法传递到外部方法
Pass values from inner recursive methods to outer methods
我从 http://algorithms.tutorialhorizon.com/dynamic-programming-subset-sum-problem/ 中找到了以下方法,它打印数组中总和为特定数字的所有子集。
我的代码充满了用于跟踪递归调用的打印语句:
public static void find(int[] A, int currSum, int index, int sum,
int[] solution, int tot) {
if (currSum == sum) {
tot +=1;
System.out.println("\nSum found ");
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
System.out.print(" " + A[i]);
}
}
} else if (index == A.length) {
System.out.println("reached end");
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
System.out.println("incr " + A[index] + " "+ currSum + " ");
find(A, currSum, index + 1, sum, solution, tot);
currSum -= A[index];
System.out.println("decr " + A[index] + " "+ currSum + " ");
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution, tot);
}
return;
}
我想修改这个方法,让它最后也打印出最终的解数。
我知道这个问题已经在 Whosebug 上讨论过了,我发现了一些有趣的解决方案。不过,我想知道是否有办法修改这个特定的方法。
我的想法是创建一个整数 "tot",一旦找到解决方案,我就将其加 1,然后将更新后的值传递给每个递归调用。但是最终值将在内部递归调用之一中找到,我不知道如何将最终值传递给外部方法。
如果您想在递归调用中获得解决方案计数,最好的方法是在每个方法调用中传递一个可变引用。一旦获得解决方案,请更新可变引用。在这里,可变引用很重要,因为:
- 原始类型很难通过递归调用传播,因为 return 类型需要相应地维护和更新。
- 不可变类型(如
Integer
)不会在递归调用中保持值。
解决方案:
- 使用
AtomicInteger
- 使用原始
int
数组
两者都能解决你的问题。您应该检查 null
引用或数组长度,以减少出错的可能性。示例如下:
private static void methodWithAtomicInteger(AtomicInteger i){
i.incrementAndGet();
}
private static void methodWithIntArray(int[] i){
i[0]++;
}
public static void main(String[] args){
AtomicInteger integer = new AtomicInteger(0);
System.out.println(integer);
methodWithAtomicInteger(integer);
System.out.println(integer);
int[] values = new int[]{0};
System.out.println(values[0]);
methodWithIntArray(values);
System.out.println(values[0]);
}
我从 http://algorithms.tutorialhorizon.com/dynamic-programming-subset-sum-problem/ 中找到了以下方法,它打印数组中总和为特定数字的所有子集。
我的代码充满了用于跟踪递归调用的打印语句:
public static void find(int[] A, int currSum, int index, int sum,
int[] solution, int tot) {
if (currSum == sum) {
tot +=1;
System.out.println("\nSum found ");
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
System.out.print(" " + A[i]);
}
}
} else if (index == A.length) {
System.out.println("reached end");
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
System.out.println("incr " + A[index] + " "+ currSum + " ");
find(A, currSum, index + 1, sum, solution, tot);
currSum -= A[index];
System.out.println("decr " + A[index] + " "+ currSum + " ");
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution, tot);
}
return;
}
我想修改这个方法,让它最后也打印出最终的解数。 我知道这个问题已经在 Whosebug 上讨论过了,我发现了一些有趣的解决方案。不过,我想知道是否有办法修改这个特定的方法。 我的想法是创建一个整数 "tot",一旦找到解决方案,我就将其加 1,然后将更新后的值传递给每个递归调用。但是最终值将在内部递归调用之一中找到,我不知道如何将最终值传递给外部方法。
如果您想在递归调用中获得解决方案计数,最好的方法是在每个方法调用中传递一个可变引用。一旦获得解决方案,请更新可变引用。在这里,可变引用很重要,因为:
- 原始类型很难通过递归调用传播,因为 return 类型需要相应地维护和更新。
- 不可变类型(如
Integer
)不会在递归调用中保持值。
解决方案:
- 使用
AtomicInteger
- 使用原始
int
数组
两者都能解决你的问题。您应该检查 null
引用或数组长度,以减少出错的可能性。示例如下:
private static void methodWithAtomicInteger(AtomicInteger i){
i.incrementAndGet();
}
private static void methodWithIntArray(int[] i){
i[0]++;
}
public static void main(String[] args){
AtomicInteger integer = new AtomicInteger(0);
System.out.println(integer);
methodWithAtomicInteger(integer);
System.out.println(integer);
int[] values = new int[]{0};
System.out.println(values[0]);
methodWithIntArray(values);
System.out.println(values[0]);
}