深度优先搜索中的ArrayIndexOutOfBound

时间:2015-04-24 10:40:29

标签: java stack depth-first-search

我目前在我的角色数组中遇到了一个ArrayIndexOutOfBounds异常。我想我有很多问题。这个程序应该使用我创建的Stack类解决迷宫。这些是我的错误:

1. LinkedStack类打印"堆栈为空"并且"什么都不能删除"我不确定它是否是由索引错误或其他原因引起的。

2. IndexOutOfBoundsException我认为这是由于一个小的逻辑错误而发生的。

我目前正在使用别人的算法,因为我之前已经这样做了,但是以不同的方式。我不太确定导致错误的是什么,我猜我正在尝试访问迷宫之外的位置。例外情况发生在传递迷宫的行上,IndexOutOfBounds的值为-1。

示例迷宫(s =开始,f =完成,* =墙)

*****
*s* *
* * *
*  f*
*****

我的LinkedStack类

import java.awt.Point;
public class LinkedStack {
private Node top;

public LinkedStack() {
    top = null;
}
public boolean isEmpty() {
    return top == null;
}
public void push( Point p ) {
    top = new Node (p, top);
}
public Point pop() {
    Point retVal = new Point(0,0);
    if( isEmpty() ){
        System.out.println("Nothing to remove");
    }else{
        retVal = top.getValue();
        top = top.getNext();
    }
    return retVal;
}
public Point peek() {
    Point retVal = new Point(0,0);
    if( isEmpty() ){
        System.out.println("Stack is Empty");
    }else{
        retVal = top.getValue();
    }
    return retVal;
}
public String toString(){
    String s = "";
    Node n = top;
    while( n != null ){
        s = s + n.getValue() + " ";
        n = n.getNext();
    }
    return s;
}
}

UPDATED Main,fixed IndexOutOfBounds正在获取StackOverFlow

//Creates an empty stack and calls method to get starting point
public static void solveDFS( char [][] maze ){
    LinkedStack stack = new LinkedStack();
    Point start = findPoint( maze,'s' );
    findPath( maze,start,stack );

}
//Finds the point of the start and finish by searching array
private static Point findPoint( char [][] maze, char c ) {
    for ( int i = 0; i < maze.length; i++ ) {
        for ( int j = 0; j < maze[i].length; j++ ) {
            if ( maze[i][j] == c ) {
                return new Point(i, j);
            }
        }
    }
    return null;
}
//Should mark location of path taken with '.'
//Should check neighboring spots of location (up,right,down,left)
//Should check if valid locations
public static boolean findPath( char [][] maze, Point location, LinkedStack stack ){
    boolean hasSolution = false;
    stack.push(location);

    do{
        maze[location.x][location.y] = '.';

        if( location.y > 0 ){
            if( maze[location.x][location.y - 1] == ' '){
                stack.push(new Point( location.x, location.y - 1));
                maze[location.x][location.y - 1] = '.';
            }
        }
        if( location.y < maze[location.x].length ){
            if( maze[location.x][location.y + 1] == ' '){
                stack.push(new Point( location.x, location.y + 1));
                maze[location.x][location.y + 1] = '.';
            }
        }
        if( location.x < maze.length ){
            if( maze[location.x + 1][location.y] == ' '){
                stack.push(new Point( location.x + 1, location.y ));
                maze[location.x + 1][location.y] = '.';
            }
        }
        if( location.x > 0 ){
            if( maze[location.x - 1][location.y] == ' '){
                stack.push(new Point( location.x - 1, location.y ));
                maze[location.x - 1][location.y] = '.';
            }
        }
        if( maze[location.x][location.y] == 'f' ){
             hasSolution = true;
        }

        location = stack.peek();
        stack.pop();
        findPath( maze,location,stack );
    }while( !location.equals('f') && !stack.isEmpty() );
    return hasSolution;
}

2 个答案:

答案 0 :(得分:1)

每当您尝试获取可能不存在的索引时,您应该进行边界检查。

E.g。如果maze[location.x][location.y + 1]

y + 1 > maze[location.x].length将抛出IndexOutOfBoundsException

更新:StackOverflow例外。

我认为这是因为你总是在评估while循环的条件之前进行递归findPath调用。这意味着您永远不会退出do-while循环。

您需要添加一个终止递归调用的条件。

答案 1 :(得分:1)

(注意:我假设迷宫的左上角是迷宫[0] [0],X是水平的,Y是垂直的。)

你的核心问题不是在这些点上检查是否处于迷宫的边缘:

    if( maze[location.x][location.y - 1] == ' '){
        stack.push(new Point( location.x, location.y - 1));
        maze[location.x][location.y - 1] = '.';
    }

^如果location位于迷宫顶部的任何位置,则会失败。

    if( maze[location.x][location.y + 1] == ' '){
        stack.push(new Point( location.x, location.y + 1));
        maze[location.x][location.y + 1] = '.';
    }

^如果location位于迷宫底部边缘的任何位置,则会失败。

    if( maze[location.x + 1][location.y] == ' '){
        stack.push(new Point( location.x + 1, location.y ));
        maze[location.x + 1][location.y] = '.';
    }

^如果location位于迷宫右边缘的任何地方,则会失败。

    if( maze[location.x - 1][location.y] == ' '){
        stack.push(new Point( location.x - 1, location.y ));
        maze[location.x - 1][location.y] = '.';
    }

^如果location位于迷宫左边缘的任何位置,则会失败。

所以你可以将这4张支票包装成自己的支票:

if(location.y > 0) {
    if( maze[location.x][location.y - 1] == ' '){
        stack.push(new Point( location.x, location.y - 1));
        maze[location.x][location.y - 1] = '.';
    }
}

if(location.y < maze[location.x].length) {
    if( maze[location.x][location.y + 1] == ' '){
        stack.push(new Point( location.x, location.y + 1));
        maze[location.x][location.y + 1] = '.';
    }
}

if(location.x < maze.length) {
    if( maze[location.x + 1][location.y] == ' '){
        stack.push(new Point( location.x + 1, location.y ));
        maze[location.x + 1][location.y] = '.';
    }
}

if(location.x > 0) {
    if( maze[location.x - 1][location.y] == ' '){
        stack.push(new Point( location.x - 1, location.y ));
        maze[location.x - 1][location.y] = '.';
    }
}

现在他们只会检查相邻的瓷砖,如果他们在逻辑上能够。