我试图递归地穿越迷宫,并且收到堆栈溢出错误,我了解该问题,但无法解决。我是否需要创建一个单独的数组来保存该数组中已访问的所有值,或者是否有其他方法可以使用更少的代码行来提高效率?
任何建议将不胜感激。
这里是输入;
5 6 // Row,Col
1 1 // Start Pos
3 4 // End Pos
1 1 1 1 1
1 0 0 0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 1
1 1 1 1 1
当前代码:
public class Solve {
private static int [][] MazeArray;
private static int Rows;
private static int Cols;
private static Point end = new Point();
private static Point start = new Point();
public static void ReadFileMakeMaze() {
Scanner in = new Scanner(System.in);
System.out.print("Select File: "); // Choose file
String fileName = in.nextLine();
fileName = fileName.trim();
String Buffer = "";
String[] Buffer2;
String[] MazeBuffer;
int Counter = 0;
try {
// Read input file
BufferedReader ReadFileContents = new BufferedReader(new FileReader(fileName+".txt"));
Buffer = ReadFileContents.readLine();
MazeBuffer = Buffer.split(" ");
// Creating MazeArray according to rows and columns from input file.
Rows = Integer.parseInt(MazeBuffer[0]);
Cols = Integer.parseInt(MazeBuffer[1]);
MazeArray = new int[Rows][Cols];
// Retrieving start locations and adding them to an X and Y coordinate.
String[] StartPoints = ReadFileContents.readLine().split(" ");
start.x = Integer.parseInt(StartPoints[0]);
start.y = Integer.parseInt(StartPoints[1]);
// Retrieving end locations and adding them to an X and Y coordinate.
String[] EndPoints = ReadFileContents.readLine().split(" ");
end.x = Integer.parseInt(EndPoints[0]);
end.y = Integer.parseInt(EndPoints[1]);
while(ReadFileContents.ready()) {
Buffer = ReadFileContents.readLine();
Buffer2 = Buffer.split(" ");
for(int i = 0; i < Buffer2.length; i++) {
MazeArray[Counter][i] = Integer.parseInt(Buffer2[i]); // Adding file Maze to MazeArray.
}
Counter ++;
}
}
catch(Exception e){
System.out.println(e); // No files found.
}
System.out.println(SolveMaze(start.x, start.y));
}
public static boolean SolveMaze(int x,int y) {
Print(); // Printing the maze
if(ReachedEnd(x,y)) {
MazeArray[x][y] = 5; // 5 represents the end
System.out.println(Arrays.deepToString(MazeArray));
return true;
}else if(MazeArray[x][y] == 1 || MazeArray[x][y] == 8){
return false;
}else {
MazeArray[x][y] = 8; // Marking the path with 8's
start.x = x;
start.y = y;
// Checking all directions
if(MazeArray[x][y - 1] == 0 ) {
System.out.println("Left");
SolveMaze(x, y - 1);
}else if(MazeArray[x + 1][y] == 0) {
System.out.println("Down");
SolveMaze(x + 1, y);
}else if(MazeArray[x - 1][y] == 0 ) {
System.out.println("Up");
SolveMaze(x - 1, y);
}else if(MazeArray[x][y + 1] == 0 ) {
System.out.println("Right");
SolveMaze(x, y + 1);
}else {
System.out.println("Debug");
MazeArray[x][y] = 0;
start.x = x;
start.y = y;
}
}
return false;
}
public static boolean DeadEnd(int x, int y) {
return true; // Solution needed
}
public static boolean ReachedEnd(int x, int y) {
if(x == end.x && y == end.y) { // Check if the end has been reached.
return true;
}else {
return false;
}
}
public static void Print() {
System.out.println(Arrays.deepToString(MazeArray));
}
public static void main(String[] args) {
ReadFileMakeMaze();
}
}
答案 0 :(得分:1)
首先,就像您在问题中提到的那样,在SolveMaze外部创建一个静态Collection并保留“已访问”节点的列表肯定会有所帮助。如果该节点之前已被访问过,则无需再次检查。
第二,我相信上面的代码中存在一些错误。该表未正确生成到MazeArray [] []中,在“ //根据输入文件中的行和列创建MazeArray”下面交换行和列。
代码也没有“找到”路径,将数组定义为int [] array = new int [5],但是要访问它,您必须使用array [0]-> array [4],修复迷宫时发生的情况是,您从元素1,1开始,元素1,1是从左上角开始在每一行和每一列中的“ 0”。然后,根据if else语句的顺序遍历该列表。访问每个节点后,将节点值设为8。经过4次迭代后,代码将查找第二行的底部0,也就是您上方的[4] [1],现在是8,由于0是唯一的元素,可以移动到,节点向左,向右和向下看,看到1,然后转向,向上看,看到8。这样完成。
第三,不要上下检查一组“ if else”,而只是检查一组“ if”。这样,代码将遍历所有路径。然后,您可以将8保留在其中,并且实际上不会再次运行同一节点两次,从而无需使用“已访问”数组。 (尽管通常,不建议穿越时更改状态)
第四,我无法从以上代码中得到堆栈溢出错误,因此无法回答实际问题。
附带说明-使用测试,这样的事情变得微不足道,从小处着手并进行构建:)如果不确定,只需签出junit。