2

数独ゲームを表す 2D 配列があります。

典型的な数独ゲームと同じように、ゲームのエラーをチェックしようとしています:

行、列、または 3x3 の正方形内で数字 (1 ~ 9) が繰り返されることはありません。空のセルはありません。

私はJavaに非常に慣れていないので、これに取り組むには限られた知識しかありませんでした。すべてのセルを比較する長い if, else ステートメントを試すつもりでした。-1 が繰り返されたため、うまくいきませんでした。(-1 は空の正方形を表します)。私はこれを回避しようとしましたが、この if ステートメントはあまりにも面倒であり、より良い方法が必要であることに気付きました。

これを行う最善の方法は、ネストされた for ループを使用して、各行、列、および 3x3 の正方形を通過することだと思います。一方、空のセルを確認すると、わかったと思います。(2D 配列内の -1 のステートメント チェック用にネストされています)。

行、列、または 3x3 の正方形のすべての数字を合計することも考えていました。45 に等しくない場合、ゲームは不完全なままになりますか?

繰り返し値をチェックする限り、ネストされた for を実装する方法がわかりません。

編集:少し明確にさせてください。繰り返し値をチェックしたくはありません。繰り返し値がある場合、ゲームを不完全なままにしておきたいだけです。(たとえば、繰り返し値を許可しても、実際の数独パズルのようにゲームに勝つことはできません)。45メソッドに追加するのが最もうまくいくと思います。

4

4 に答える 4

4

ゲーム ボード全体にすべての重複がないことを確認するのではなく、新しい値が配置されたときにのみ、特定の行、列、および 3x3 の正方形に重複がないことを確認すると、物事を本当に単純化できます (プレーヤー、またはファイルからゲームをロードするとき)。

この方法では、ネストされていない 3 つのループのみが必要になります。配置される新しい値がその行、列、および 3x3 の正方形にまだ存在しないことを確認するために 1 つずつ。

また、-1 のチェックについて心配する必要はありません (値 1 ~ 9 の入力を既にエラー チェックしていると仮定します)。

注: 「行、列、または 3x3 の正方形の合計が 45 になるかどうかを確認する」は機能しません。これは良いアイデアですが、複数の重複をキャッチしません (たとえば、すべて 5 の行はパスします)。

于 2012-10-16T02:44:53.513 に答える
0

これは良い質問で、私は退屈なので、その方法の 1 つをかなり完全に説明します。もちろん、他にもたくさんあります!このアプローチは効率的ですが、特にエレガントではありません。他の人が何を思いついたのか見てみたい。

1)BitSet各行、列、および 3x3 の正方形のオブジェクトを作成します。これらを次のように配列に入れます。

// Initialize arrays
BitSet[] rows = new BitSet[9];
BitSet[] cols = new BitSet[9];
BitSet[] squares = new BitSet[9];
// Initialize the array elements
for(int i=0;i<9;i++){
    rows[i] = new BitSet(9);
    cols[i] = new BitSet(9);
    squares[i] = new BitSet(9);
}

これで、1 回のパスでグリッドを調べて、適切な行、列、正方形にビットを設定できます。「適切な」とは、i番目の行と j番目の列を見ている場合、ビットを androws[i]に設定することを意味しますcols[j]。正方形の要素にインデックスを付けるには、次のレイアウトを使用します。

0 1 2
3 4 5
6 7 8

i と j を 3 で割るだけで、上記のレイアウトの行と列を取得できます。したがって、必要なインデックスは ですi / 3 + 3 * ( j / 3 )。ここでは整数除算が行われていることに注意してください。7 / 3 == 8 / 3 == 2つまり、i と j が 8 に等しい場合、たとえば となり8 / 3 + 3 * ( 8 / 3 ) = 2 + 3 * 2 = 8ます。

すべてをまとめると、パズルが解けていないかどうかを確認するメソッドを次のように書くことができます。

public boolean hasRepeats(){
            // ...
        // initialize rows, cols, and squares as above
            // ...

    for(int i=0;i<9;i++){
        for(int j=0;j<9;j++){
            int gridValue = grid[i + 9 * j];
            if( gridValue == -1 ){
                // Skip empty squares
                continue;
            }
            // Check for repeats
            if( rows[i].get(gridValue) ){
                return true; 
            }
            rows[i].set(gridValue);
            if( cols[j].get(gridValue) ){
                return true;
            }
            cols[j].set(gridValue);
            BitSet square = squares[ i / 3 + 3 * ( j / 3 ) ]
            if( square.get( gridValue ) ){
                return true;
            }
            square.set( gridValue );
        }
    }
    return false;
}
于 2012-10-16T03:20:06.517 に答える
0

あなたは Java を初めて使用するので、3x3 の正方形を格納するために 2D 整数配列を使用していると思います。目標は、正方形に重複する整数 (-1 を除く) が存在することを検証することです。

private static final int WIDTH = 3;
private static final int HEIGHT = 3;
private static int[][] cells = new int[WIDTH][HEIGHT];

そして、2D配列を-1で初期化できます

for (int i = 0; i < WIDTH; i++) {
    for (int j = 0; j < HEIGHT; j++) {
        cells[i][j] = -1;
    }
}

簡単な方法は、リストを使用してユーザー入力を一時的に保存し、追加する入力が既に存在するかどうかを確認することです。

private static boolean validateCells() {
    boolean isValid = true;
    List<Integer> inputValues = new ArrayList<Integer>();
    for (int i = 0; i < WIDTH; i++) {
        for (int j = 0; j < HEIGHT; j++) {
            int inputValue = cells[i][j];
            if (inputValue != -1) {
                if (inputValues.contains(inputValue)) {
                    isValid = false;
                    break;
                } else {
                    inputValues.add(inputValue);
                }
            }
        }
    }
    return isValid;
}

これは明らかに効率的なアプローチではありませんが、シンプルで、Java の初心者にとって非常に理解しやすいものです。

于 2012-10-16T03:30:54.723 に答える
0

帰納法による正しい簡単な方法は、配列に 9 つの値をロードしてから、次のことを行うことです。

  1. 重複しないようにセットに変換する
  2. 配列に戻す
  3. 配列をソートする

次に、値が有効であることを保証するために 3 つのことを確認できます。

  1. 最初の数字 (つまり、最小の数字) が 1 であることを確認します
  2. 最後の数字 (つまり、最大の数字) が 9 であることを確認します
  3. 配列の長さが 9 であることを確認します (したがって、実際には 9 つの数値がすべて存在します)。
于 2012-10-16T03:58:20.293 に答える