1

私は約 1 か月間 Java を学んでおり、このサイトで他の人の質問 (および回答) を読んで多くのことを学びました。これは以前に尋ねられたとは思いません(しかし、もしあれば、ポインタをいただければ幸いです...)

以下のコードでは、インデントされていないほとんどすべてがエラー チェックの出力であるため、コードは見た目よりもかなり短くなっています。このコードは、再帰を使用して、ボールをビンnumBallsに配置できるすべての方法をリストしようとする私の試みです。numBins

主な質問: メソッドはnumBins< 3で正常に動作します。numBinsが 3 に設定されるとすぐendListに、(再帰呼び出しで) フィールドに複数の「行」があり、すぐ下のループで j が 1 に達するとすぐに、indexListフィールド変わります。たとえばcalling testList = distributeBallsInBins(1,3,"");、メイン メソッド (構成されているため) では、2 行目の {0 1 0} から {0 0 1} への変更につながりますindexList(出力に示されているように) が、方法/理由がわかりません私が行ったすべてが次の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());

または、ループを繰り返すたびに新しい配列を作成しますnewLinej

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 に答える