繁体   English   中英

为什么我的递归Java方法中的字段会更改?

[英]Why does the field in my recursive Java method change?

我已经学习Java大约一个月了,通过阅读本网站上其他人的问题(和答案),我学到了很多东西。 我认为以前没有问过这个问题(但是如果有的话,我将不胜感激指针...)

在下面的代码中,几乎所有未缩进的内容都是错误检查打印输出,因此代码比看起来短了很多。 该代码是我尝试使用递归列出numBalls球可以放在numBins箱中的所有方式的尝试。

主要问题:该方法适用于numBins <3。当numBins设置为3时, endList字段(在递归调用中)具有1个以上的“行”,并且j在下面的直接循环中击中1 , indexList字段将更改。 例如, calling testList = distributeBallsInBins(1,3,""); 在main方法(按配置)中,导致indexList的第二行从{0 1 0}更改为{0 0 1}(如输出所示),但我看不到它如何/为什么我完成的所有操作都移到下一个j时发生了更改(即从j = 0到j = 1)

第二个问题:我用int[]替换了所有Integer[]出现的地方,似乎没有什么区别。 应该有吗? 我想我需要阅读更多有关原始类型和引用类型之间的区别的信息,但是我真的不太了解这里的区别。

预先谢谢迈克

import java.util.*;

public class testRecursion
{
     public static List<Integer[]> distributeBallsInBins(int numBalls, int numBins, String tmpTxt)
    {
        if (numBins==1)
        {
            List<Integer[]> lastList = new ArrayList<Integer[]>();
            lastList.add((new Integer[] {numBalls}));
            return lastList;
        }
        else if (numBalls==0)
        {
            List<Integer[]> lastList = new ArrayList<Integer[]>();
            Integer[] tmpNum = new Integer[numBins];
            for (int k=0; k<numBins; k++)
                tmpNum[k] = 0;
            lastList.add(tmpNum);
            return lastList;
        }
        else
        {
            List<Integer[]> indexList = new ArrayList<Integer[]>();
            for (int i=numBalls; i>=0; i--)
            {
                Integer[] newLine = new Integer[numBins];
                newLine[0] = i;
                List<Integer[]> endList = distributeBallsInBins((numBalls-i), (numBins-1), (tmpTxt + "    "));
                for (int j=0; j<endList.size(); j++)
                {
                    Integer[] newLineEnd = endList.get(j);
                    for (int k=0; k<numBins-1; k++)
                        newLine[k+1] = newLineEnd[k]; 
                    indexList.add(newLine);
                }
            }
        return indexList;
        }
    }

    public static void main(String[] args)
    {
        List<Integer[]> testList = distributeBallsInBins(1,3,"");
    }
}

您的问题是,您总是在修改相同的数组并将其插入到结果列表中。 由于Java处理每个引用的所有对象,因此最终将得到一个包含相同数组的列表。

因此,您需要先clone阵列,然后再将其添加到列表中:

indexList.add(newLine.clone());

或在每次循环j -loop时创建new的newLine数组:

for (int j = 0; j < endList.size(); j++) {
    Integer[] newLine = new Integer[numBins];
    newLine[0] = i;
    Integer[] newLineEnd = endList.get(j);
    for (int k = 0; k < numBins - 1; k++)
        newLine[k + 1] = newLineEnd[k];
    indexList.add(newLine);
} // next j

关于对象与基元:更改为int[]并没有帮助,因为array本身仍然是Object ,因此通过引用传递。

只需替换此行

indexList.add(newLine);

带线

indexList.add(newLine.clone());

这将工作......这将通过新数组而不是通过旧数组的引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM