我的问题是当我在第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);
}
}
答案 0 :(得分:0)
您使用递归的唯一目的就是跟踪需要检查的位置。因此,您可以将这些位置放入队列,然后继续处理从队列开头弹出的位置,直到队列为空。循环的主体看起来像您的flow
方法的主体(除了初始测试将continue
循环而不是return
进行循环),但是您将使用初始值来初始化队列(i,j)位置,然后用这些位置的排队代替递归调用。