1

わかりました、私は再帰を使用する必要があるこの関数を持っています。これは、ユーザーによって座標(i、j)、ゼロが指定された mineswepper(int[][] m) を検索します。ゼロは、その地域の近くに地雷がないことを意味します。それがゼロの場合、私の関数はこのゼロと、この最初のゼロの周りのゼロを 1 つの位置の範囲で表示する必要があります。これは、見つかったすべてのゼロに対して再帰的に行う必要があります。

私の int[][]v は私のビジョン マトリックスです。以前は、すべての場所についてステータス (1 => 場所を表示できます。0 => ?) を個別に表示していたので、すべてのマトリックス m を印刷すると、行列 v に 1 がある場所のみを確認できます。

1-. ゼロを見つけた2

2-. 見つけられるゼロがなくなるまで、他のゼロを見つけるために周りを検索します

?   ?   ?   ?
?   ?   ?   ?
?   ?   0   ?
?   ?   ?   ?
?   ?   ?   ?

視覚行列 v でどのように見えるか

0   0   0   0
0   0   0   0
0   0   1   0
0   0   0   0
0   0   0   0



?   ?   ?   ?
?   ?   ?   ?
?   ?   0   ?
?   ?   ?   0
?   ?   ?   ?

視覚行列 v でどのように見えるか

0   0   0   0
0   0   0   0
0   0   1   0
0   0   0   1
0   0   0   0

 public void zeros(int[][]m, int[][]v, int j, int i){

            v[i][j] = 1;

            for(int a = Math.max(0, i-1); a < Math.min(5,i+2); a++){
              for(int b = Math.max(0,j-1); b < Math.min(5,j+2); b++){
                 if(m[a][b] == 0){
                     i = a;
                     j = b;
                    zeros( m, v, i, j);}

                }
            }         
   }

fors は、指定された i と j の周りのすべての場所を検索します。

エラーが表示されます。スレッド「メイン」の例外 java.lang.StackOverflowError. なぜだかわかりません。多分誰かが再帰性を作るのに早い方法を与えるか、私の間違いを教えてくれるでしょう。

4

7 に答える 7

2

これまでのところすべて良い。ただし、次を修正します

これらの 2 行を削除します。

i = a;
j = b;

次のように呼び出します。

zeros( m, v, a, b);

それ以外の:

zeros( m, v, i, j);

これも変更します:

public void zeros(int[][]m, int[][]v, int j, int i)

それも:

public void zeros(int[][]m, int[][]v, int i, int j)

これを行う:

if(m[a][b] == 0 && v[a][b]==0)
于 2013-09-30T20:09:29.937 に答える
2

運動定数を使用した私の解決策を考えてみましょう:

int [] movx ={-1, -1, -1, 0, 0, 1, 1, 1};
int [] movy ={-1, 0, 1, -1, 1, -1, 0, 1};

これは、移動元のオフセットです(x,y)。だからあなたの方法は

public void zeros(int[][] m, int[][] v, int x, int y) {

    //Already visited?  
    if (v[x][y] == 1) return;

    //Mark as visited   
    v[x][y] = 1;

    for (int i = 0; i < 8; i++){
        //neighbors coordinates
        int nx = x + movx[i];
        int ny = y + movy[i];

         //check boundaries
         if (nx >= 0 && nx < m.length && ny >= 0 && ny < m[x].length){

             //if there is no mine check it
             if (m[nx][ny] == 0)
                 zeros(m, v, nx, ny);
         }
    }               
}

たとえば(x=2,y=2)、隣人がいる場合は次のようになります。

(x=1,y=1)
(x=1,y=2)
(x=1,y=3)
(x=2,y=1)
(x=2,y=2)
(x=2,y=3)
(x=3,y=1)
(x=3,y=2)
(x=3,y=3)
于 2013-09-30T20:33:31.557 に答える
1

これは、Flood Fill 操作と非常によく似ています。ウィキペディアには、これを実現するためのメタコードがあります。再帰的ではありませんが、うまく機能するはずです。

于 2013-09-30T20:09:14.383 に答える
1

エラー java.lang.StackOverflowError は、再帰を扱うときに最も一般的なエラーの 1 つです。これは、再帰で無限ループを作成したことを意味し、スタックはすべての再帰呼び出しを処理するのに十分な大きさではありません。

周囲の正方形で関数を再帰的に呼び出すとどうなるか考えてみてください。元の正方形を編集しないため、再度呼び出されて無限ループが作成されます。

これを修正すると、問題は解決します。

于 2013-09-30T20:14:18.073 に答える
0

i と j を再帰的に渡していますが、これらの変数の値を変更していないため、呼び出しは無期限に発生します

于 2013-09-30T20:17:02.917 に答える
0

「m[a][b] == 0」を実行する前に、a と b が m の範囲外にないことを確認する必要があります。現在、そのチェックを行っていないと思います。

于 2013-09-30T20:08:54.707 に答える
0

私はそれを得ると思います。

fors の if にこの追加条件を追加するだけです。

if(m[a][b] == 0 && v[a][b]!= 1)

そのため、マトリックス ビジョン v で 1 を含む場所には戻ることができません。

于 2013-09-30T20:40:17.837 に答える