RStudio中手动实现阶乘函数输出不稳定问题求助
解决R语言递归/记忆化阶乘的输出问题
递归阶乘的问题与修复
你遇到的“有时输出中间步骤、有时只输出最终结果”的问题,核心原因是你的递归函数在每一层递归里都调用了print()——每次递归到下一层时,都会打印当前的计算值,所以调用recursion(5)时会依次输出1、2、6、24、120。
至于你说的“30%概率只输出120”,大概率是你误操作了调用方式:比如把函数返回值赋值给了变量(result <- recursion(5)),或者在重复运行代码时混淆了函数内部打印和R自动打印返回值的行为。
正确的递归写法应该是让函数只返回结果,不在递归过程中打印,把print()换成return()即可:
recursion <- function(n) { if(n <= 1) { return(1) } else { return(n * recursion(n-1)) } }
调用时直接写recursion(5),R会自动打印最终的返回值120;如果需要显式打印,用print(recursion(5))效果一样,再也不会输出中间步骤。
记忆化阶乘的问题与修复
你的记忆化代码有两个关键bug:
- 递归调用错了函数:你写的
values[x] <<- x * factorial(x-1)调用的是R内置的factorial(),而不是你自己定义的记忆化函数Factorial_mem。这导致记忆化完全没生效——计算x的阶乘时,直接用内置函数算出x-1的结果,不会填充values向量的前面元素,所以values里只有第一个元素和第x个元素有值,其余都是NA。 - 不必要的
print(values):你在函数里直接打印了整个缓存向量,这就是为什么会输出[1] 1 NA NA NA 120的原因。
修复后的记忆化函数如下:
memoization <- function(){ values <- 1 # 初始化,values[1]对应0!和1!的值 Factorial_mem <- function(x){ if(x < 0){ stop("Factorials can only be computed when x is equal to, or greater than, zero") } if(x == 0 || x == 1){ return(1) } # 扩展缓存向量长度(如果需要) if(length(values) < x){ values <<- `length<-`(values, x) } # 缓存命中直接返回 if(!is.na(values[x])){ return(values[x]) } # 递归调用自己的记忆化函数,填充缓存 values[x] <<- x * Factorial_mem(x-1) # 返回当前计算的阶乘值 return(values[x]) } Factorial_mem }
使用时先初始化记忆化函数,再调用:
fact_memo <- memoization() fact_memo(5) # 输出120 fact_memo(4) # 直接返回缓存的24,无需重新计算
这样修改后,每次调用只会返回最终的阶乘值,不会输出带NA的缓存向量,而且真正实现了记忆化——后续调用已计算过的数值时,会直接使用缓存结果。
关于“概率性输出”的补充
你提到的输出不稳定和RStudio无关,主要是因为函数内部的print()语句、错误的递归调用,以及可能的调用方式差异(比如是否赋值、是否有残留的缓存)导致的。只要按照上面的方法修改,就能得到稳定的单一输出。
内容的提问来源于stack exchange,提问作者Nick Bohl
相关产品推荐
相关产品推荐

