1

我已经学习 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),它发生了变化

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

提前谢谢你,迈克

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,"");
    }
}
4

2 回答 2

0

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

因此,您需要在clone将数组添加到列表之前将其添加到数组中:

indexList.add(newLine.clone());

或者newLine每次迭代j-loop 时创建新数组:

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,因此通过引用传递。

于 2013-07-25T06:35:03.527 回答
0

只需替换此行

indexList.add(newLine);

带线

indexList.add(newLine.clone());

这将起作用......这将传递新数组而不是传递旧数组的引用......

于 2013-07-25T07:27:01.033 回答