导致此StackOverflowError的原因是什么?

时间:2015-06-22 23:32:57

标签: java recursion stack-overflow decision-tree

我错过了什么?我有我的基本情况,看起来“左侧”运行没有问题,但是当右侧执行时我得到错误。我对递归很新,我确信答案很明显,但我似乎找不到它。

基本上,我有一个列表,我正在尝试查看该列表中有多少子集,当添加时,等于常量D.我使用带有true和false值的ArrayList来创建决策树,然后使用该列表使用“test”查找总和,这是一个全局ArrayList。

public void recSubSetSum(ArrayList<Boolean> subSetList){

    if(calcSumOfList(subSetList) == D)
        subsetsFound++;

    else if(calcSumOfList(subSetList) < D){
        for (int i = 0; i < test.size(); i++) {
            ArrayList leftList = new ArrayList<>();
            copyList(leftList, subSetList);

            leftList.add(true);
            if(calcSumOfList(leftList) < D)
                recSubSetSum(leftList);


            ArrayList rightList = new ArrayList<>();
            copyList(rightList, subSetList);

            rightList.add(false);
            if(calcSumOfList(rightList) < D)
                recSubSetSum(rightList); //this is where the error occurs 

        }//for

    }//else

    else{
        subsetsNotFound++;
    }
}


    public int calcSumOfList(ArrayList<Boolean> boolList){
    int sum = 0;
    int j =0; //I used j because it was giving me a outOfBoundsException when I uses i
    for (int i = 0; i < boolList.size(); i++) {
        if(boolList.get(i) == true){
            sum+= test.get(j);

            j++;
        }

    }//for
    return sum;
}//calc sum of list

提前致谢!

2 个答案:

答案 0 :(得分:1)

因为向右递归永远不会增加子集的总和,所以递归可以永远继续。如果您继续向数组中添加false,则始终会遇到< D情况,并且您将始终执行递归rightList的代码。

即使calcSumOfList大于您正在查看的实际列表,

rightList也不会抛出异常,因为它永远不必访问test,因为boolList.get(i)将始终返回false(因为rightList除了false值之外什么都没有。

您需要添加基本案例,以便subSetListtest的大小相同,并且无法再添加。

答案 1 :(得分:0)

这是因为错误行之前的if语句不正确:

if(calcSumOfList(rightList) < D)
       recSubSetSum(rightList); //this is where the error occurs 

外部if语句已经满足条件:

else if(calcSumOfList(subSetList) < D){

这是因为您正在将subSetList的内容复制到rightList,如果条目为calcSumOfList,则false不会添加到列表的值中rightList与原始subSetList的值相同。因此该方法每次都会递归,导致StackOverflow。