3

サイコロを振るモジュールを作成しています。y 面の x ダイスが与えられた場合、考えられるすべてのロールの組み合わせのリストを作成しようとしています。

このコードは、それぞれ 1、2、3 のラベルが付いた 3 つの面を持つ 3 つのサイコロを想定しています (「マジック ナンバー」を使用していることは認識していますが、これは基本コードを単純化して機能させるための試みにすぎません)。

        int[] set = { 1, 1, 1 };
        list = diceroll.recurse(0,0, list, set);

...

    public ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
        if(index < 3){
//          System.out.print("\n(looping on "+index+")\n");
            for(int k=1;k<=3;k++){
//              System.out.print("setting i"+index+" to "+k+" ");
                set[index] = k;
                dump(set);
                recurse(index+1, i, list, set);
            }
        }
        return list;
    }

(dump() は list[] の内容を表示するだけの簡単な方法です。変数iは現在使用されていません。)

私がやろうとしているのは、list[index] を 1 ずつインクリメントし、リスト全体の長さをステップ実行し、進むにつれてインクリメントすることです。

これは私の「最善の試み」のコードです。出力は次のとおりです。

大胆な出力は、私が探しているものです。残りを取り除く方法がわかりません。(これは、それぞれ 3 つの面を持つ 3 つのサイコロを想定しています。再帰を使用して、y 面を持つ任意の x サイコロにスケールアップできます。)

[1][1][1] [1][1][1]

[1][1][1] [1][1][2] [1][1][3] [1][2][3]

[1][2][1] [1][2][2] [1][2][3] [1][3][3]

[1][3][1] [1][3][2] [1][3][3] [2][3][3] [2][1][3]

[2][1][1] [2][1][2] [2][1][3] [2][2][3]

[2][2][1] [2][2][2] [2][2][3] [2][3][3]

[2][3][1] [2][3][2] [2][3][3] [3][3][3] [3][1][3]

[3][1][1] [3][1][2] [3][1][3] [3][2][3]

[3][2][1] [3][2][2] [3][2][3] [3][3][3]

[3][3][1] [3][3][2] [3][3][3]

書式設定についてお詫び申し上げます。

どんな助けでも大歓迎です。(この方法は、実際には非常に些細なことにデータを使用するために端を発していましたが、個人的な課題になりました。:)

編集: この問題を解決するための別のアプローチがある場合、私はすべて耳を傾けますが、現在の問題を解決し、再帰を何か有用なものにうまく使用したいと考えています.

edit2: 「簡単な修正」を含む実行中のコード。未使用の変数と奇妙なハックに注意してください。まだクリーンアップしていません。

package code.testing;

import java.util.ArrayList;

public class CodeTesting {

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        int[] set = { 1, 1, 1 };
        list = recurse(0,0, list, set);
    }

    public static ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
        if(index < 3){
//          System.out.print("\n(looping on "+index+")\n");
            for(int k=1;k<=3;k++){
//              System.out.print("setting i"+index+" to "+k+" ");
                set[index] = k;
                if (index==2){
                    dump(set);
                }
                recurse(index+1, i, list, set);
            }
        }
        return list;
    }

    static void dump(int[] arr) {
        for (int s : arr) {
            System.out.format("[%s]", s);
        }
        System.out.println();
    }
}
4

3 に答える 3

2

申し訳ありませんが、コードを書き直さなければなりませんでしたが、いくつかの修正を加えたものとほとんど同じアルゴリズムです。

public class DiceRolls {
    static void recurse(int diceNumber, int[] values, final int MAX) {
        if (diceNumber == values.length) {
            System.out.println(java.util.Arrays.toString(values));
        } else {
            for (int v = 1; v <= MAX; v++) {
                values[diceNumber] = v;
                recurse(diceNumber + 1, values, MAX);
            }
        }
    }
    public static void main(String[] args) {
        recurse(0, new int[3], 4);
    }
}

これは、標準の連符再帰ジェネレーターです。すべてを に追加する場合はint[]、それらが独立したオブジェクトであるListことを確認してください。add(values.clone())int[]


しかし、余分な出力は何ですか?

問題は、すべてのサイコロを投げ終わる前に、時期尚早にダンプしていたことです。疑似コードでは、これがあなたがしていることです:

if we're not done yet
    trying all possibilities for this dice
       dump result so far // premature dumping!
       recurse for next dice

コードを簡単に修正するには、次のようにします。

if we're not done yet
    trying all possibilities for this dice
       recurse for next dice
else, we're done, so
    dump result // timely!

したがって、Java 実装に戻ると、修正はステートメントのケースに移動dump(set);するだけです。elseif (index < 3)

于 2010-06-07T17:45:03.090 に答える
1

これは非再帰的な代替手段です。2つの定数を変更して、さまざまなサイコロとさまざまな数のサイコロのすべての組み合わせを計算します。

package utils;

public class Dice {
    private static int FACES = 3;
    private static int NUMBER_OF_DICE = 3;

    public static void main(String[] args) {
        int start = createPair(1);
        int end = createPair(FACES);
        for (int i = start; i <= end; i++) {
            String combination = Integer.toString(i, FACES+1);
            if (combination.indexOf('0') < 0)
                System.out.println(combination);
        }
    }

    private static int createPair(int number) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < NUMBER_OF_DICE; i++) {
            sb.append(number);
        }
        return Integer.parseInt(sb.toString(), FACES+1);
    }
}
于 2010-06-07T18:00:01.897 に答える
1

dump()の場合のみ呼び出しindex == 2ます。

ちなみに、未使用iのようです。listそして動詞は「recur」です。:)

于 2010-06-07T17:39:38.907 に答える