Java递归求解迷宫时出现无限递归错误的排查求助
Java递归求解迷宫时出现无限递归错误的排查求助
嗨,我看了你的代码,发现无限递归的问题根源在于递归过程中允许重新回到已经标记为路径的位置(包括起点),导致程序一直在循环调用同一个位置的递归方法。
问题具体分析
你的代码里,起点用+标记,路径也用+标记,但在递归的终止条件里,并没有排除已经是+的位置。举个例子:当你从起点出发走到某个位置,然后又绕回起点时,因为起点还是+,而你的终止条件只排除了墙X和死路.,所以程序会再次调用起点的递归方法,无限循环下去。
另外,你原来的代码里对起点的处理有点特殊(不修改起点的+),这反而让起点成为了递归的“漏洞”——永远可以重复进入。
修复方案
我们可以通过两个关键修改来解决这个问题:
- 在递归终止条件里,排除已经标记为路径的
+,避免重复访问。 - 临时修改起点的标记,让初始递归可以正常进入,同时后续不会再回到起点。
下面是修改后的完整代码,我标注了关键修改点:
import java.io.*; import java.util.*; public class Main { public static char[][] maze; public static int rows, cols, beginR, beginC; public static boolean solve = false; public static void main(String[] args) { boolean load = loadmaze("maze.txt"); if (load == false) { System.out.println("Failed to load Maze"); return; } // --- 关键修改1:临时将起点改为空格,避免初始递归被终止条件拦截 --- maze[beginR][beginC] = ' '; if (solverMaze(beginR, beginC)) { // 找到终点后,恢复起点的+标记 maze[beginR][beginC] = '+'; System.out.println("Congrats you beat the Maze!"); } else { // 未找到终点,同样恢复起点 maze[beginR][beginC] = '+'; System.out.println("Not found"); } pMaze(); } public static boolean loadmaze(String filename) { File file = new File(filename); try(Scanner scan = new Scanner(file)) { rows = scan.nextInt(); cols = scan.nextInt(); scan.nextLine(); maze = new char[rows][cols]; for(int i = 0; i < rows; i++) { String lines = scan.nextLine(); for(int l = 0; l < cols; l++) { maze[i][l] = lines.charAt(l); if(maze[i][l] == '+') { beginR = i; beginC = l; } } } return true; } catch(FileNotFoundException e) { System.out.println("Error in loading file"); } catch(Exception e) { System.out.println("Error in read maze"); } return false; } private static boolean solverMaze(int row, int column) { // --- 关键修改2:新增排除已经标记为路径的+ --- if( row < 0 || column < 0 || row >= rows || column >= cols || maze[row][column] == 'X' || maze[row][column] == '.' || maze[row][column] == '+' || solve) { return false; } if(maze[row][column] == '-') { solve = true; return true; } // 统一标记当前位置为路径+,不再区分是否是起点 maze[row][column] = '+'; if(solverMaze(row + 1, column) || solverMaze(row - 1, column) || solverMaze(row, column + 1) || solverMaze(row, column - 1)) { return true; } // 死路标记为. maze[row][column] = '.'; return false; } private static void pMaze() { for (char[] row : maze) { System.out.println(new String(row)); } } }
修改说明
- 起点临时修改:在调用递归前把起点改成空格,这样初始递归调用时不会被
maze[row][column] == '+'的条件拦截;找到终点或回溯后再恢复起点的+标记,符合题目要求。 - 终止条件新增+判断:所有已经标记为路径的
+都会被排除,确保每个位置只会被访问一次,彻底避免无限递归。 - 统一路径标记逻辑:去掉了原来对起点的特殊处理,不管当前位置是什么(除了终点),都统一标记为
+,逻辑更清晰,也避免了起点的递归漏洞。
这样修改后,你的递归迷宫求解应该就能正常运行,不会再出现无限递归的问题啦!
备注:内容来源于stack exchange,提问作者Cool Dude
相关产品推荐
相关产品推荐

