3 recursion f# tail-recursion factorial
自然数的阶乘(任何大于或等于的数0
)是该数乘以其自身的阶乘减去1,其中阶乘0
被定义为1
.
例如:
0! = 1
1! = 1 * 0!
2! = 2 * 1!
3! = 3 * 2!
4! = 4 * 3!
5! = 5 * 4!
Run Code Online (Sandbox Code Playgroud)
写这个的另一种方式是乘之间的所有自然数1
和n
为n!
:
5! = 1 * 2 * 3 * 4 * 5
Run Code Online (Sandbox Code Playgroud)
如何用F#中的递归函数表达这个?我应该用递归函数来做吗?
//Factorials!
let factorial n =
result = ?
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 23
如何,选项1:
let rec factorial n =
match n with
| 0 | 1 -> 1
| _ -> n * factorial(n-1)
Run Code Online (Sandbox Code Playgroud)
如何,选项2(尾递归,编译成循环):
let factorial n =
let rec loop i acc =
match i with
| 0 | 1 -> acc
| _ -> loop (i-1) (acc * i)
loop n 1
Run Code Online (Sandbox Code Playgroud)
应该:不,请看我的回答:
虽然在F#中使用Tail Recursion,但在什么时候使用?
我提倡经常避免迭代和递归,而支持高阶函数.但是如果你刚刚开始,也许不要过多担心这个建议.(但后来看看例如@ ChaosPandion的答案,或者例如
let factorial n = [1..n] |> List.fold (*) 1
Run Code Online (Sandbox Code Playgroud)
甚至:
let factorial n = [1..n] |> List.reduce (*) // doesn't require the 2nd parameter
Run Code Online (Sandbox Code Playgroud)
这是另一个例子:
let factorial (num:int) =
seq { for n in [1..num] -> n }
|> Seq.reduce (fun acc n -> acc * n)
Run Code Online (Sandbox Code Playgroud)
这个例子可能更清楚一点:
let factorial num =
[1..num] |> Seq.fold (fun acc n -> acc * n) 1
Run Code Online (Sandbox Code Playgroud)
Brian的答案是最实用的,但这是继续传递风格的解决方案:
let rec factorial n =
let rec loopk i k =
match i with
| 0 | 1 -> k i
| _ -> loopk (i-1) (fun r -> k (i * r))
in loopk n (fun r -> r)
Run Code Online (Sandbox Code Playgroud)