private boolean[][] computeMainOutline(boolean[][] outline) {
int pixelValue[][] = new int [width][height];
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
if(pixelValue[x][y] == 0) {
ArrayList<Point2D.Double> path = new ArrayList<>();
findPath(x, y, outline, pixelValue, path );
}
return new boolean[1][1]; // to avoid compilation error
}
private void findPath(int x, int y, boolean[][] outline, int pixelValue [][], ArrayList<Point2D.Double> path ) {
path.add( new Point2D.Double(x, y));
if(x > 0 && outline[x - 1][y] == true) // check right
findPath(x - 1, y, outline, pixelValue, path);
if(x < width && outline[x + 1][y] == true) // check left
findPath(x + 1, y, outline, pixelValue, path);
if(y < height && outline[x][y + 1] == true) // check up
findPath(x, y + 1, outline, pixelValue, path );
if(y > 0 && outline[x][y - 1] == true) // check down
findPath(x, y - 1, outline, pixelValue, path);
}
The above method is giving a StackOverflowError
and I don't know why.
The method computeMainOutline
iterates through the whole outline
array and the pixelValue
array which are both the same size. If the "value" has not been calculated for a specific coordinate then the findPath
function will recursively calculate a path. A path is basically how many "true" array elements are next to each other. The method to calculate the value is not added but my first problem is finding a path.
Moreover if I put a print statement right after path.add( new Point2D.Double( x, y));
to print path.size()
inside the recursive method, the size sequence is not consistent it might print(1,2,3,4,2,3,4), why is that?
UPDATE
Corrected it like this, but it will still spark a stack overflow...
private boolean[][] computeMainOutline(boolean[][] outline) {
int pixelValue[][] = new int [width][height];
boolean visited[][] = new boolean[width][height];
for(int x = 0; x < width; x++)
for(int y = 0; y < height; y++)
if(visited[x][y] == false) {
ArrayList<Point2D.Double> path = new ArrayList<>();
findPath(x, y, outline, pixelValue, path, visited );
}
return new boolean[1][1]; // to avoid compilation error
}
private void findPath(int x, int y, boolean[][] outline, int pixelValue [][], ArrayList<Point2D.Double> path, boolean visited [][] ) {
path.add( new Point2D.Double(x, y));
visited[x][y] = true;
if( x > 0 && visited[x - 1][y] == false && outline[x - 1][y] == true) // check right
findPath(x - 1, y, outline, pixelValue, path, visited);
if( x < width - 1 &&visited[x + 1][y] == false && outline[x + 1][y] == true) // check left
findPath(x + 1, y, outline, pixelValue, path, visited);
if( y < height - 1 && visited[x][y + 1] == false && outline[x][y + 1] == true) // check up
findPath(x, y + 1, outline, pixelValue, path, visited );
if( y > 0 && visited[x][y - 1] == false && outline[x][y - 1] == true) // check down
findPath(x, y - 1, outline, pixelValue, path, visited);
}
The way you have done your recursion is wrong. While making a recursive method each call puts the previous call on a stack. If you're recursion runs forever there won't be enough room in the stack to go one level deeper causing a Stack Overflow.
Here's the problem. You haven't marked at each time step what has been visited. Imagine this is your grid. The cell in quotes is the (x,y)
of our method
"T" F F T F F "T" F F
T F F (next step) "T" F F (next) T F F
T F F T F F T F F
It goes back to the state it's already visited. Hence you'll put infinite method calls in the stack.
Solution
Pass another array to the method with what cells have been visited and as you go to a cell mark it as visited. This would avoid you going back to something you've seen before
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.