0

私は有名な 8 パズルを解こうとしています。3*3 の正方形に 1 つの空きスロットと 8 つの数字が埋められており、解けば元の状態に戻ります。

これを行うには、パズルを表す0〜9の数字を格納するarraylistの「状態」があります。

解決策には、多数の可能な移動状態を生成することが含まれます。つまり、行われたすべての合法的な移動とその結果のパズルを保存します。これは以下のメソッドを使用して行われますが、swapAndStore はパスごとに元の渡された配列を編集しません。代わりに、その下の genSuccessors() で呼び出されると、最初の if 条件で正常に機能し、最初の if の結果に次の if 条件を適用します。「oldBoard」という新しいパズル状態を作成して、元の入力パズルを将来の参照用に保存することで問題を解決したと思いましたが、これも機能しませんでした。友人は、これは私がよく理解できない参照の問題に関係している可能性があると私に言いました。x = 0、y = 1の場合、Javaはswap(x、y)を実行しないため、x = 1、y = 0になることは理解していますが、これがここでどのように適用されるかはわかりません。提案?

   private void swapAndStore(int d1, int d2, ArrayList<State> s)
{
    //int[] cpy = copyBoard(curBoard);
    int[] cpy = new int [curBoard.length];
    System.arraycopy(curBoard,0,cpy,0,curBoard.length);
    int[] oldBoard = new int [curBoard.length];
    System.arraycopy(curBoard,0,oldBoard,0,curBoard.length);
    int temp = cpy[d1];
    cpy[d1] = cpy[d2];
    cpy[d2] = temp;
    s.add((new State(cpy)));
    curBoard = oldBoard;
    System.out.println("swapandstore storing" );
    s.get(s.size()-1).printState();

}

public ArrayList<State> genSuccessors()
{
    ArrayList<State> successors = new ArrayList<State>();
    int hole = getHole();

    // try to generate a state by sliding a tile leftwise into the hole
    // if we CAN slide into the hole
    if (hole != 0 && hole != 3 && hole != 6)
    {
        /*
         * we can slide leftwise into the hole, so generate a new state for
         * this condition and throw it into successors
         */;
        System.out.println("left");
        swapAndStore(hole - 1, hole, successors);
    }

    // try to generate a state by sliding a tile topwise into the hole
    if (hole != 6 && hole != 7 && hole != 8)
    {
        System.out.println("top");
        swapAndStore(hole + 3, hole, successors);
    }
4

1 に答える 1

1

Java は常に値渡しです。

プリミティブは値渡しです。オブジェクト参照は値渡しです。

これは、参照の値を変更できないことを意味します。ただし、オブジェクトの場合、変更可能であれば状態を変更できます。

だからあなたはこれを行うことができます:

package cruft;

import java.io.PrintStream;

/**
 * ArraySwapDemo description here
 * @author Michael
 * @link
 * @since 12/3/12 9:48 PM
 */
public class ArraySwapDemo {

    public static void main(String[] args) {
        System.out.println(String.format("before: %s", arrayToString(args)));
        swapValues(args, 0, args.length-1);
        System.out.println(String.format("after : %s", arrayToString(args)));
    }

    // No checks for proper indexes, but you get the idea.
    private static void swapValues(String[] args, int i, int j) {
        String temp = args[i];
        args[i] = args[j];
        args[j] = temp;
    }

    public static String arrayToString(String [] array) {
        StringBuffer buffer = new StringBuffer(1024);
        buffer.append('{');
        for (int i = 0; i < array.length-1; ++i) {
           buffer.append(array[i]).append(',');
        }
        buffer.append(array[array.length-1]).append('}');
        return buffer.toString();
    }

}

コマンド ラインで 4 つの文字列 (foo bar baz bat) を指定して実行すると、次の結果が得られます。

java cruft.ArraySwapDemo foo bar baz bat
before: {foo,bar,baz,bat}
after : {bat,bar,baz,foo}

Process finished with exit code 0
于 2012-12-04T02:46:07.333 に答える