[英]stack overflow exception in recursion java
My problem is when i change the first parameter into over 300 in line 133, i get a java.lang.StackOverflowError in line 37.This line is a recursion. 我的问题是当我在第133行将第一个参数更改为超过300时,我在第37行得到了一个java.lang.StackOverflowError。这一行是递归。 How can i solve this?
我怎么解决这个问题?
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
In here I was changing gird values to get test cases. 在这里,我正在改变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);
}
}
The only thing you are using recursion for is to keep track of the locations that need to be checked. 您使用递归的唯一方法是跟踪需要检查的位置。 So you could instead have a queue of those locations, and keep processing the one popped off the head of the queue until the queue is empty.
因此,您可以改为拥有这些位置的队列,并继续处理从队列头部弹出的队列,直到队列为空。 The body of the loop would look like the body of your
flow
method (except the initial tests would continue
the loop instead of return
ing), but you would initialize the queue with the initial (i,j) location, and replace the recursive calls with enqueues of those locations. 循环的主体看起来像你的
flow
方法的主体(除了初始测试将continue
循环而不是return
),但你会用初始(i,j)位置初始化队列,并替换递归调用这些地点的队列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.