hasell 基础题解(02)

斐波那契数列问题

【问题】输出斐波那契数列的前100项
1,1,2,3,5,8,13,…
有些书上是从0开始,0,1,1,2,3,…
这种写法数学上更完美一点吧。

如果用 haskell 来解,有很多方法。先来个其它语言中常用来引入递归的写法。
其实,haskell 中递归是家常便饭,没有递归可以说举步维艰,因为 haskell中没有循环,要想重复一件事,只能递归。

fei :: Int -> Integer
fei 1 = 1
fei 2 = 1
fei n = fei (n-1) + fei (n-2)

main = print $ map fei [1..20]

这和其它语言中的写法没啥大不同。haskell 支持函数参数的模式匹配,同一个函数可以写多个定义,从上到下匹配,配上哪个用哪个。
这里只显示了前 20 项,如果用前 100项,那程序就假死状态了(其它语言里也一样),这只是个算法效率问题。有各种避免的方法。
另外注意这个函数的结果增长很快,不能用Int, 这里用了 Integer,haskell中的无上限整数。

haskell 有一个其它语言中很少有的本事:支持无限的序列。因为 haskell是惰性的,只要没用到,说一个数列有限还是无限对haskell都一样。
下面的解法中, fei 就是一个无限的序列,你可不要直接对它求值,那样就不会返回了。

fei = f [1,1] where
    f (x:y:ys) = x : f (y:x+y:ys)
main = print $ take 20 fei

可以把 20 改为 100 看看,很轻松就算出来了。

其实,haskell中有一个函数 iterate,它是产生器。(python中也有生成器)
需要一个函数,该函数吃入一个值,吐出一个新值,再吃入新值,吐出一个更新的值,如此,就形成了一个新值的序列。

fei' = iterate f (1,1) where
    f (x,y) = (y,x+y)
fei = map fst fei'

main = print $ take 20 fei

这里的fei'并非有什么特别之处,它只是一个普通的名字而已。haskell中经常这样用,
x + x’ + x’’ 这是不是更数学啊?
fei’ 是一个无限列表,我们对它map操作,得到一个新的无限列表。
只要没说用它,怎么无限都可以,这是 haskell 强大,方便的地方。

产生器也可以用于列表推导的源集,这样表达上更简单一些。
如下:

fei = [ fst x | x <- iterate (\(x,y) -> (y,x+y)) (1,1)]
main = print $ take 20 fei

这里的 iterate 的第一个参数用了lambda表达式。
当一个函数很短小,临时用一下时,一般都用 lambda 形式,避免大动干戈去定义一个有名字的函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值