0

我阅读了有关 java recorsion 的文档,我以为我已经理解了,但是当我尝试在以下示例中使用它时,它无法按预期工作。

我是一个类account,它有amount并且可以有其他子帐户。我会实现一种方法getSum,它必须返回账户金额和所有子账户金额的总和。在下面的代码中,该方法的调用getSumm()应该返回 550,但它的行为很奇怪。有人可以帮忙吗?

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);

}

}
4

5 回答 5

5

您因未正确封装而使事情复杂化。这意味着您必须正确的参数传递给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;
   }

}
于 2012-09-25T21:33:33.560 回答
2

您对 getSum 的终止条件之一是

return amount;

其中amount是一个类作用域变量。这可能不是你想要的。您可能应该返回result

此外,结果被定义为类作用域变量。getSum 应该是本地的。

于 2012-09-25T21:31:22.760 回答
2

你的逻辑有点不靠谱。

getSum 不应带参数,因为 subAccounts 成员变量已经是对象的一部分。

此外,您还在成员变量中收集内部总和。使用局部变量来避免问题。

正如每个人都已经说过的那样...确保您实际上没有为此使用递归。这只是演示如何使用recusion,这样就可以了。

这是更正后的程序:

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);
    }
}
于 2012-09-25T21:33:05.257 回答
1

这是一个工作的、更简单、更安全的版本:

public double getSum(){
    double result = this.amount;
    if(this.subAccounts !=null){
        for (Balance subAccount : this.subAccounts) {
            result = result + subAccount.getSum();
        }
    }
    return result;
}

你用简单的方式调用它:bs1.getSum()。这个想法很简单直观:sum是金额+所有子账户金额的总和。

于 2012-09-25T21:35:23.847 回答
0

请参阅 Nicholas 的答案以获得更完整的答案

尝试

double sum= bs1.getSum(bs1);

这不直观..但会给你你想要的答案。您应该稍微重构一下 getSum() 以获得直观的功能。

此外,您需要将最后一次返回更改为:

    return result + amount;
于 2012-09-25T21:31:46.073 回答