作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
let rec f n =
match n with
| 0 | 1 | 2 -> 1
| _ -> f (n - 2) + f (n - 3)
没有CPS,没有Memoization,尾递归怎么实现?
最佳答案
let f n = Seq.unfold (fun (x, y, z) -> Some(x, (y, z, x + y))) (1I, 1I, 1I)
|> Seq.nth n
或者更好:
let lambda (x, y, z) = x, (y, z, x + y)
let combinator = Seq.unfold (lambda >> Some) (1I, 1I, 1I)
let f n = combinator |> Seq.nth n
要了解这里发生了什么,请参阅 this片段。它定义了斐波那契算法,和你的很相似。
UPD 这里包含三个组件:
i
个元素的 lambda;i
上运行递归的组合器;和你已经要求了一个尾递归代码,实际上有两种方法:制作你自己的组合器,就像@Tomas 所做的那样,或者利用现有的组合器,Seq.unfold
,它肯定是尾递归的。我更喜欢第二种方法,因为我可以将整个代码拆分为一组 let
语句。
关于f# - 如何让这个简单的递归关系(差分方程)尾递归呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12465510/
我是一名优秀的程序员,十分优秀!