R语言函数可打印网格路径但无法存储,求解决方法
问题分析与解决方案
你的代码核心问题在于作用域处理错误:在pathmaker函数中对paths的赋值没有修改全局变量,仅在函数局部创建了同名变量,导致最终storepaths拿到的是空的局部变量;同时路径索引使用字符串类型,不符合你按数字序号调用的需求。
修改方案1:修正全局变量作用域(简单直接)
通过<<-运算符修改全局paths,并改用数字索引实现序号调用:
numbmatrix <- rbind(c(rep(0,times=8)),cbind(c(rep(0,times=8)),matrix(1:48,nrow=8,ncol=6),c(rep(0,times=8))),c(rep(0,times=8))) possmoves <- cbind(rbind(1,-1),rbind(1,0),rbind(1,1),rbind(0,1),rbind(-1,1),rbind(-1,0),rbind(-1,-1),rbind(0,-1)) oneawayfrom <- function(startrow,startcol){ visited <- matrix(0,nrow=10,ncol=8) oneaway <- list() for (i in 1:8){ dx <- possmoves[1,i] dy <- possmoves[2,i] nextmove <- numbmatrix[startrow + dy,startcol + dx] if (nextmove == 0 | visited[startrow + dy,startcol + dx] != 0 ){next} if (visited[startrow + dy,startcol + dx] == 0 && nextmove !=0){ visited[startrow + dy,startcol + dx] <- 1 oneaway[[length(oneaway)+1]]<- nextmove } } return(oneaway) } options <- list() for (i in 2:9){ for (n in 2:7){ adjacent <- oneawayfrom(i,n) cell_key <- as.character(numbmatrix[i,n]) options[[cell_key]] <- adjacent } } paths <- list() path_counter <- 1 pathmaker <- function(current_path){ if (length(current_path) == 48) { # 使用<<-修改全局paths,直接用数字作为索引 paths[[path_counter]] <<- current_path print(paste(current_path, collapse=",")) # 打印格式更清晰 path_counter <<- path_counter + 1 return() # 路径完成后无需返回值 } last_element <- current_path[length(current_path)] for(i in seq_along(options[[as.character(last_element)]])){ adjacent_number <- options[[as.character(last_element)]][i] if (!(adjacent_number %in% current_path)){ pathmaker(c(current_path, adjacent_number)) } } } # 生成路径 pathmaker(current_path=c(numbmatrix[2,2])) # 赋值给storepaths用于后续调用 storepaths <- paths
修改说明:
- 用
paths[[path_counter]] <<- current_path修改全局paths,确保所有递归分支共享同一个路径列表 - 直接使用数字
path_counter作为列表索引,实现storepaths[[1]]、storepaths[[2]]这类序号调用 - 路径完成时直接
return(),无需返回paths,全局变量已同步更新
修改方案2:无全局变量的函数式写法(更规范)
避免全局变量副作用,通过递归返回值传递路径数据:
numbmatrix <- rbind(c(rep(0,times=8)),cbind(c(rep(0,times=8)),matrix(1:48,nrow=8,ncol=6),c(rep(0,times=8))),c(rep(0,times=8))) possmoves <- cbind(rbind(1,-1),rbind(1,0),rbind(1,1),rbind(0,1),rbind(-1,1),rbind(-1,0),rbind(-1,-1),rbind(0,-1)) oneawayfrom <- function(startrow,startcol){ visited <- matrix(0,nrow=10,ncol=8) oneaway <- list() for (i in 1:8){ dx <- possmoves[1,i] dy <- possmoves[2,i] nextmove <- numbmatrix[startrow + dy,startcol + dx] if (nextmove == 0 | visited[startrow + dy,startcol + dx] != 0 ){next} if (visited[startrow + dy,startcol + dx] == 0 && nextmove !=0){ visited[startrow + dy,startcol + dx] <- 1 oneaway[[length(oneaway)+1]]<- nextmove } } return(oneaway) } options <- list() for (i in 2:9){ for (n in 2:7){ adjacent <- oneawayfrom(i,n) cell_key <- as.character(numbmatrix[i,n]) options[[cell_key]] <- adjacent } } pathmaker <- function(current_path) { if (length(current_path) == 48) { return(list(current_path)) } last_element <- current_path[length(current_path)] all_paths <- list() for(i in seq_along(options[[as.character(last_element)]])){ adjacent_number <- options[[as.character(last_element)]][i] if (!(adjacent_number %in% current_path)){ # 递归收集子路径 sub_paths <- pathmaker(c(current_path, adjacent_number)) all_paths <- c(all_paths, sub_paths) } } return(all_paths) } # 直接调用函数获取所有路径 storepaths <- pathmaker(current_path=c(numbmatrix[2,2]))
优势:
- 完全不依赖全局变量,所有数据通过函数返回值传递,避免作用域冲突
- 最终
storepaths直接存储所有路径,可直接用storepaths[[i]]调用第i条路径
内容的提问来源于stack exchange,提问作者Stephen Dorn
相关产品推荐
相关产品推荐

