尽量还是避免递回吧,以下理由请参考
1. 递回的逻辑需要很清楚,虽然程式很简单
2. 递回的程式很难debug
3. 递回会有C stack limit (下面例子中,x=10, N=358是上限)
4. while通常还是快一点,请参考下面的benchmark
library(microbenchmark)
func <- function(w) {
return(w + 1)
}
recussive_func <- function(x, N = 10, n = 1) {
if (n == N) {
return(func(x))
} else {
return(recussive_func(func(x), N, n+1))
}
}
while_loop_func <- function(x, N = 10, n = 1) {
repeat {
x <- func(x)
if (n == N)
break
n <- n + 1
}
return(x)
}
microbenchmark(recussive_func(10, N = 358),
while_loop_func(10, N = 358), times = 10L)
# Unit: microseconds
# expr min lq mean median uq max neval
# recussive_func(10, N = 358) 279.1 286.0 446.68 331.2 656.8 688.4 10
# while_loop_func(10, N = 358) 91.4 92.1 98.90 93.0 103.1 128.8 10
※ 引述《andrew43 (讨厌有好心推文后删文者)》之铭言:
: 写一个递回最简单的例子与教学供你参考
: # 一个预先写好的 function,可以回值 w + 1
: func <-
: function(w){
: return(w + 1)
: }
: # N = 10 默认做10次
: # n 是递回时的计数器,提供递回时串接资讯用的,使用时不要指派值
: myFunc <-
: function(x, N = 10, n = NULL) {
: # 一开始 n 为默认 NULL,先把它指定为 1
: # 若已经递回过了,n 不是 NULL,跳过不管
: if (is.null(n)) {
: n <- 1
: }
: # 令 res1 为“x + 1”
: res1 <- func(x)
: cat("Call func():", n, "time(s)\n") # 搞懂后可以把这行删除
: # 若 n 为 N 则回传 res1,完成。
: # 否则(还小于 N)递回,其中以 res1(而不是 x)为第一个参数
: # 并令计数器加 1
: if (n == N) {
: return(res1)
: } else {
: n <- n + 1
: myFunc(res1, N, n)
: }
: }
: # 丢入 10,做 5 次 func()
: # 结果应是 10 +1 +1 +1 +1 +1 = 15
: myFunc(10, N = 5)
: # Call func(): 1 time(s)
: # Call func(): 2 time(s)
: # Call func(): 3 time(s)
: # Call func(): 4 time(s)
: # Call func(): 5 time(s)
: # [1] 15
: ※ 引述《penispower (笔就是力量)》之铭言:
: : 想做的事情:
: : 自行写好了一个函数
: : 想要将一个起始值丢进去得到函数值
: : 再将函数值再丢进去取得第二个函数值
: : 如此反复操作取得10000个值并放入一个向量内
: : 自己的想法是写for loop
: : 但不太会写
: : 希望板上有高手可以指点迷津
: : 感激不尽