简体   繁体   中英

Recursive Stack Overflow & Odd Object Reference Java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM