Re: [問題] 將一數字重複取函數值

作者: celestialgod (天)   2020-03-17 15:50:46
盡量還是避免遞迴吧,以下理由請參考
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
: : 但不太會寫
: : 希望板上有高手可以指點迷津
: : 感激不盡
作者: andrew43 (討厭有好心推文後刪文者)   2020-03-17 17:06:00
不知道為什麼,我機器上可以遞迴遠超過358... 但不到10k不過這個例子的條件確實不用遞迴較好。
作者: penispower (penispower)   2020-03-17 18:01:00
實際操作確實會有次數的限制
作者: TreeMan (好啊...)   2020-03-17 21:50:00
推~

Links booklink

Contact Us: admin [ a t ] ucptt.com