R语言递归迷宫求解函数报错:argument is of length zero问题排查
R递归迷宫求解函数报错修复
问题重现
尝试用递归实现R语言迷宫求解,矩阵规则:
- 0 = 空白可通行
- 1 = 墙体(不可通行)
- 2 = 终点
- 3 = 已访问区域
迷宫初始化代码:
data = c(rep(1, 20), c(4,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1), c(1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,2), rep(1, 20)) maze = matrix(data, 4, 20, byrow = TRUE)
递归求解函数:
search = function(x, y){ if (maze[x,y] == 2){ print(paste('i am in point', x, y)) return(TRUE) } else if (maze[x,y]==1){ print(paste('wall in point', x, y)) return(FALSE) } else if (maze[x,y]==3){ print(paste('visited point', x, y)) return(FALSE) } #set as marked print(paste('visited point', x, y)) maze[x,y] = 3 if((x < length(maze[,1]) & search(x+1, y)) | (y > 1 & search(x,y-1)) | (x > 1 & search(x-1,y)) | (y < length(maze[1,]) & search(x,y+1))){ return(TRUE) } return(FALSE) } search(x= 2, y = 1)
运行后报错:
[1] "visited point 2 1" [1] "wall in point 3 1" Error in if (maze[x, y] == 2) { : argument is of length zero
错误原因
- 索引越界未检查:递归调用时没有先判断坐标(x,y)是否在矩阵有效范围内。比如当x=4(矩阵最大行数)时,调用
search(x+1,y)会传入x=5,此时maze[5,y]返回长度为0的空向量,导致if (maze[x,y] == 2)的条件不合法(if要求条件是长度为1的逻辑值)。 - 全局变量修改失效:函数内用
maze[x,y] = 3是局部赋值,不会修改全局环境中的maze矩阵,导致已访问标记无法被后续递归调用识别,可能引发重复访问或逻辑错误。 - 起点值不合法:迷宫中(2,1)位置的值是4,不属于规则定义的0/1/2/3,会跳过所有前置判断直接进入标记步骤,后续逻辑会因异常值出现问题。
修复方案
步骤1:修正迷宫初始化(修复起点值)
将(2,1)位置的4改为0,符合空白区域规则:
data = c(rep(1, 20), c(0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1), c(1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,2), rep(1, 20)) maze = matrix(data, 4, 20, byrow = TRUE)
步骤2:修正递归函数
search = function(x, y){ # 优先检查坐标合法性,避免索引越界 max_row = nrow(maze) max_col = ncol(maze) if (x < 1 || x > max_row || y < 1 || y > max_col) { return(FALSE) } # 按规则判断当前单元格状态 if (maze[x,y] == 2){ print(paste('到达终点:', x, y)) return(TRUE) } else if (maze[x,y] == 1){ print(paste('遇到墙体:', x, y)) return(FALSE) } else if (maze[x,y] == 3){ print(paste('已访问过:', x, y)) return(FALSE) } # 标记为已访问,使用<<-修改全局变量 print(paste('标记已访问:', x, y)) maze[x,y] <<- 3 # 递归探索四个方向,任意方向找到终点则返回TRUE if (search(x+1, y) || search(x, y-1) || search(x-1, y) || search(x, y+1)) { return(TRUE) } # 所有方向都走不通,回溯返回FALSE return(FALSE) } # 调用求解函数 search(x=2, y=1)
关键修复点说明
- 坐标合法性检查:在判断单元格值之前先确认x/y在矩阵范围内,彻底避免索引越界导致的空值报错。
- 全局赋值
<<-:确保函数内对maze的修改能同步到全局环境,让后续递归调用能识别已访问区域。 - 简化逻辑判断:利用R的逻辑短路特性(只要前面的条件为TRUE,后面的不会执行)提升递归效率。
内容的提问来源于stack exchange,提问作者tararuj4
相关产品推荐
相关产品推荐

