如何在此函数中正确使用递归?

时间:2013-09-30 20:00:20

标签: java recursion minesweeper

好的,我有这个需要使用递归的函数,在用户给定坐标(i,j)的情况下搜索mineswepper(int [] [] m),为零。零意味着该地点附近没有地雷。如果它是零,那么我的函数应该在一个局部的范围内显示零和零初始零点周围的零。这必须以递归的方式进行,对于找到的所有零。

我的int [] [] v是我的视觉矩阵,它用于给出和状态(1 =>你可以显示位置,0 =>保持?)单独为所有位置,所以当我打印所有矩阵m我们只能看到矩阵v中有1的位置。

1-。找到了零点

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);}

                }
            }         
   }

在给定的i和j周围的所有位置都要进行搜索。

它显示了错误,线程“main”java.lang.StackOverflowError中的异常。 我不明白为什么。也许有人可以通过一种方式来提出递归,或者告诉我我的错误。

7 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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)

答案 2 :(得分:1)

这听起来与洪水填充操作非常相似。 Wikipedia has some meta-code要做到这一点。这不是递归的,但应该运作良好。

答案 3 :(得分:1)

错误java.lang.StackOverflowError是处理递归时最常见的错误之一。这意味着您在递归中创建了一个无限循环,并且堆栈不够大,无法处理所有递归调用。

想想当你在周围的方块上递归调用你的函数时会发生什么。因为你不编辑原始方块,所以再次调用它,创建一个无限循环。

解决此问题并解决您的问题。

答案 4 :(得分:0)

在你做“m [a] [b] == 0”之前,你需要检查以确保a和b不在m的范围之外。我不认为你现在正在进行那项检查。

答案 5 :(得分:0)

你递归地传递i和j,但是你没有修改这些变量的值,所以调用将无限期地发生

答案 6 :(得分:0)

我认为我明白了。

只是在fors中添加这个额外条件。

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

因此我们无法返回矩阵视觉v中具有1的任何位置