无法使递归函数在Java中工作
我阅读了关于java恢复的文档,我认为我已经理解了它,但是当我在下面的示例中尝试使用它时,它并没有像预期的那样工作 我有一个类帐户,它有金额,可以有其他子帐户。我将实现一个方法getSum,它必须返回帐户金额和所有子帐户金额的总和。在下面的代码中,方法getSumm的调用应该返回550,但它的行为很奇怪。有人能帮忙吗无法使递归函数在Java中工作,java,Java,我阅读了关于java恢复的文档,我认为我已经理解了它,但是当我在下面的示例中尝试使用它时,它并没有像预期的那样工作 我有一个类帐户,它有金额,可以有其他子帐户。我将实现一个方法getSum,它必须返回帐户金额和所有子帐户金额的总和。在下面的代码中,方法getSumm的调用应该返回550,但它的行为很奇怪。有人能帮忙吗 public class Balance{ ArrayList<Balance> subAccounts = new ArrayList<Balance&
public class Balance{
ArrayList<Balance> subAccounts = new ArrayList<Balance>();
String accountID = null;
Double amount = null;
double result=0;
public double getSum(ArrayList<Balance> subAccounts){
if(subAccounts !=null && subAccounts.size()>0){
for (int i = 0; i < subAccounts.size(); i++) {
result = result + getSum(subAccounts.get(i).subAccounts);
}
}
else {
return amount;
}
return result;
}
public static void main(String[] args) {
Balance bs1 = new Balance();
Balance bs2 = new Balance();
Balance bs3 = new Balance();
bs1.amount=100.0;
bs2.amount=150.0;
bs3.amount=300.0;
ArrayList<Balance> subAccounts1 = new ArrayList<Balance>();
bs2.subAccounts=null;
bs3.subAccounts=null;
subAccounts1.add(bs2);
subAccounts1.add(bs3);
bs1.subAccounts=subAccounts1;
double sum= bs1.getSum(subAccounts1);
System.out.println(sum);
}
}
getSum的终止条件之一是
return amount;
其中amount是一个类作用域变量。那可能不是你想要的。您可能应该返回结果
此外,result被定义为类范围的变量。它应该是getSum的本地版本。有关更完整的答案,请参阅Nicholas的答案 试一试 这不是直觉。。但我会给你你想要的答案。您应该稍微重新构造getSum,以获得直观的函数 此外,您需要将上一次返回更改为:
return result + amount;
你的逻辑有点模糊 getSum不应接受参数,因为subAccounts成员变量已经是对象的一部分 您还收集了成员变量中的内部和。使用局部变量来避免问题 正如每个人都说过的。。。确保您没有实际为此使用递归。这只是演示如何使用递归,这样就可以了 下面是正确的程序:
import java.util.ArrayList;
public class Balance {
ArrayList<Balance> subAccounts = new ArrayList<Balance>();
String accountID = null;
Double amount = null;
public double getSum() {
if (subAccounts != null) {
Double sum = 0.0;
for (int i = 0; i < subAccounts.size(); i++) {
sum += subAccounts.get(i).getSum();
}
return amount + sum;
} else {
return amount;
}
}
public static void main(String[] args) {
Balance bs1 = new Balance();
Balance bs2 = new Balance();
Balance bs3 = new Balance();
bs1.amount = 100.0;
bs2.amount = 150.0;
bs3.amount = 300.0;
ArrayList<Balance> subAccounts1 = new ArrayList<Balance>();
bs2.subAccounts = null;
bs3.subAccounts = null;
subAccounts1.add(bs2);
subAccounts1.add(bs3);
bs1.subAccounts = subAccounts1;
double sum = bs1.getSum();
System.out.println(sum);
}
}
由于没有正确封装,您正在使事情复杂化。这意味着您必须将正确的参数传递给getSum…,并且由于您可能传递了错误的参数,因此缺少封装和错误的参数确保了错误的答案 关键是不要再要求调用者了解getSum如何。。。作品账户应该能够在没有帮助的情况下计算自己的金额。毕竟,一个帐户应该已经拥有类中的数据,那么为什么需要其他人告诉它这些数据呢
public class Account {
// A list of subAccounts, each which
// is responsible for its own value.
private List<Account> subAccounts;
// value in this account, not assigned
// to subAccounts
private double value;
public double getSum() {
double sum = this.value;
for (Account account : subAccounts) {
sum += account.getSum();
}
return sum;
}
}
这是一个有效、更简单、更安全的版本:
public double getSum(){
double result = this.amount;
if(this.subAccounts !=null){
for (Balance subAccount : this.subAccounts) {
result = result + subAccount.getSum();
}
}
return result;
}
您可以使用simple:bs1.getSum来调用它。这个想法很简单,直观:总和是所有子账户的金额+总和。它是如何表现的奇怪?“是不是给出了错误的答案,比如450?”哈奇特读了这个问题。很明显这是不对的。哈哈,每个人都在发布他们的解决方案,并被投票系统标记。这让我想起了我上计算机课的时候。子帐户列表不应该是该方法的参数。一个账户知道它的子账户。一旦API正确,实现就变得显而易见。如果这不是一个已建立的引用,那么它应该是。bs1是他实现getSum的正确参数吗?
public double getSum(){
double result = this.amount;
if(this.subAccounts !=null){
for (Balance subAccount : this.subAccounts) {
result = result + subAccount.getSum();
}
}
return result;
}