递归java中的堆栈溢出异常

时间:2017-04-29 10:55:44

标签: java recursion stack-overflow

我的问题是当我在第133行将第一个参数更改为超过300时,我在第37行得到了一个java.lang.StackOverflowError。这一行是递归。我该如何解决这个问题?

public class PathFindingOnSquaredGrid {

// given an N-by-N matrix of open cells, return an N-by-N matrix
// of cells reachable from the top
public static boolean[][] flow(boolean[][] open) {
    int N = open.length;

    boolean[][] full = new boolean[N][N];
    for (int j = 0; j < N; j++) {
        flow(open, full, 0, j);
    }

    return full;
}

 // determine set of open/blocked cells using depth first search
 public static void flow(boolean[][] open, boolean[][] full, int i, int j) {
    int N = open.length;

    // base cases
    if (i < 0 || i >= N) return;    // invalid row
    if (j < 0 || j >= N) return;    // invalid column
    if (!open[i][j]) return;        // not an open cell
    if (full[i][j]) return;         // already marked as open

    full[i][j] = true;

    flow(open, full, i+1, j);   // down line 37
    flow(open, full, i, j+1);   // right line 38
    flow(open, full, i, j-1);   // left line 39
    flow(open, full, i-1, j);   // up line 40
}

// does the system percolate?
public static boolean percolates(boolean[][] open) {
    int N = open.length;

    boolean[][] full = flow(open);
    for (int j = 0; j < N; j++) {
        if (full[N-1][j]) return true;
    }

    return false;
}

//does the system percolate vertically in a direct way?
public static boolean percolatesDirect(boolean[][] open) {
    int N = open.length;

    boolean[][] full = flow(open);
    int directPerc = 0;
    for (int j = 0; j < N; j++) {
        if (full[N-1][j]) {
            // StdOut.println("Hello");
            directPerc = 1;
            int rowabove = N-2;
            for (int i = rowabove; i >= 0; i--) {
                if (full[i][j]) {
                     //StdOut.println("i: " + i + " j: " + j + " " + full[i][j]);
                    directPerc++;
                }
                else break;
            }
        }
    }

    // StdOut.println("Direct Percolation is: " + directPerc);
    if (directPerc == N) return true; 
    else return false;
}

// draw the N-by-N boolean matrix to standard draw
public static void show(boolean[][] a, boolean which) {
    int N = a.length;
    StdDraw.setXscale(-1, N);;
    StdDraw.setYscale(-1, N);
    StdDraw.setPenColor(StdDraw.BLACK);
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (a[i][j] == which)
                StdDraw.square(j, N-i-1, .5);
            else StdDraw.filledSquare(j, N-i-1, .5);
}

// draw the N-by-N boolean matrix to standard draw, including the points A (x1, y1) and B (x2,y2) to be marked by a circle
public static void show(boolean[][] a, boolean which, int x1, int y1, int x2, int y2) {
    int N = a.length;
    StdDraw.setXscale(-1, N);;
    StdDraw.setYscale(-1, N);
    StdDraw.setPenColor(StdDraw.BLACK);
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            if (a[i][j] == which)
                if ((i == x1 && j == y1) ||(i == x2 && j == y2)) {
                    StdDraw.circle(j, N-i-1, .5);

                }
                else StdDraw.square(j, N-i-1, .5);
            else StdDraw.filledSquare(j, N-i-1, .5);
}

// return a random N-by-N boolean matrix, where each entry is
// true with probability p
public static boolean[][] random(int N, double p) {
    boolean[][] a = new boolean[N][N];
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            a[i][j] = StdRandom.bernoulli(p);
    return a;
}



// test client
public static void main(String[] args) {

    ArrayList<Node> path=null;
    Stopwatch timer;


   // The following will generate a 10x10 squared grid with relatively few 
   obstacles in it
   //The lower the second parameter, the more obstacles (black cells) are 
   generated

在这里,我正在改变gird值以获得测试用例。

    boolean[][] randomlyGenMatrix = random(350, 0.8); //line133

    StdArrayIO.print(randomlyGenMatrix);
    show(randomlyGenMatrix, true);

    System.out.println();
    //System.out.println("The system percolates: " + percolates(randomlyGenMatrix));

    System.out.println();
    //System.out.println("The system percolates directly: " + percolatesDirect(randomlyGenMatrix));
    System.out.println();


    Stopwatch timerFlow = new Stopwatch();

    Scanner in = new Scanner(System.in);
    System.out.println("Enter i for A > ");
    int Ai = in.nextInt();

    System.out.println("Enter j for A > ");
    int Aj = in.nextInt();

    System.out.println("Enter i for B > ");
    int Bi = in.nextInt();

    System.out.println("Enter j for B > ");
    int Bj = in.nextInt();


 // THIS IS AN EXAMPLE ONLY ON HOW TO USE THE JAVA INTERNAL WATCH
    // Stop the clock ticking in order to capture the time being spent on inputting the coordinates
    // You should position this command accordingly in order to perform the algorithmic analysis
    StdOut.println("Elapsed time = " + timerFlow.elapsedTime());

            //StdDraw.point(Ai, Bj);           

    // System.out.println("Coordinates for A: [" + Ai + "," + Aj + "]");
    // System.out.println("Coordinates for B: [" + Bi + "," + Bj + "]");

    show(randomlyGenMatrix, true, Ai, Aj, Bi, Bj);


     String dis="";
     while(!dis.equalsIgnoreCase("X")){
        //Selecting the path
        System.out.println("Enter Distance: (M)Manhattan|(E)Euclidean|(C)Chebyshev|(X)Exit");         
        dis=in.next();
        timer=new Stopwatch();
        path = new DijkstraAlgorithm(dis).distance(randomlyGenMatrix, Ai, Aj, Bi, Bj);

        System.out.println("Elapsed time: "+timer.elapsedTime());

        //Draw the path in the grid
        for (Node node : path) {
            StdDraw.filledCircle(node.y, 10 - node.x -1, .2);


        }
  }
    System.exit(0);

}

}

1 个答案:

答案 0 :(得分:0)

您使用递归的唯一目的就是跟踪需要检查的位置。因此,您可以将这些位置放入队列,然后继续处理从队列开头弹出的位置,直到队列为空。循环的主体看起来像您的flow方法的主体(除了初始测试将continue循环而不是return进行循环),但是您将使用初始值来初始化队列(i,j)位置,然后用这些位置的排队代替递归调用。