所以我正在做一個任務,我必須找到第 n 個斐波那契數,我遇到了下面顯示的這個想法,但是這會回傳一個串列,我只想回傳最終數字,例如 fibo 3 會給我 [0,1,1,2,3,5,8,13],除了我只想回傳 13,有什么辦法可以做到嗎?這是我第一次使用 Haskell,我也是第一次學習函式式編程,感謝任何幫助。謝謝
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n
fiboHelper :: Integral x => [x]->x->x->x->[x]
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l [y x] [y x y]) (x y) (y x y) (n-1)
uj5u.com熱心網友回復:
是的,您可以在向下遞回堆疊時跟蹤最后兩個步驟。
fibo :: Integral x => x -> x
fibo a
| a < 3 = 1
| otherwise = go 2 1 1 where
go a' b' c'
| a' == a = c'
| otherwise = go (a' 1) (c') (b' c')
順便說一句,我學會了在 Haskell 中創建無限斐波那契數列的一種非常有趣的方法如下:
fibs = 1 : scanl ( ) 1 fibs
與此結合take,last您可以實作您正在尋找的任何解決方案。
take 5 fibs
-- produces [1,1,2,3,5]
last $ take 5 fibs
-- produces 5
uj5u.com熱心網友回復:
您可以使用包含兩個變數的輔助函式:第一項和第二項,以及每個
fibo :: (Integral a, Integral b) => a -> b
fibo 0 = 0
fibo n = fiboHelper 0 1 (n-1)
fiboHelper :: (Integral a, Integral b) => a -> a -> b -> a
fiboHelper si si1 n
| n <= 0 = si1
| otherwise = fiboHelper si1 (si si1) (n-1)
這將產生:
Prelude> fibo 7
13
至于您問題中的演算法,通常附加在串列的右側并不是一個好主意,因為它與左運算元的大小在線性時間內運行。因此,這意味著您的演算法在 O(n 2 ) 時間內運行。您可以將其實作為:
fibo :: (Integral a, Integral b) => a -> [b]
fibo 0 = [0]
fibo n = 0 : fiboHelper 0 1 (n-1)
fiboHelper :: (Integral a, Integral b) => a -> a -> b -> [a]
fiboHelper si si1 n
| n < 0 = []
| otherwise = si1 : fiboHelper si1 (si si1) (n-1)
這將產生:
Prelude> fibo 7
[0,1,1,2,3,5,8,13]
uj5u.com熱心網友回復:
您只需要跟蹤最后兩個斐波那契數,而不是串列,以便您可以將它們加在一起以進行下一次迭代。您想要的遞回關系可以使用定義
-- replace a and b with (a b) and a, respectively, forgetting b.
helper a b n == fiboHelper (a b) a (n-1)
helper a b 1 == a
helper _ b 0 == b
(第二種情況不是絕對必要的,但避免了不必要的添加。)
隨著n變小,所需的值在第二個引數中“累積”,該值n == 0作為最終結果。
請注意,您可以通過為a和提供不同的初始值來獲得不同的系列b。例如,fibo = helper 1 0,而盧卡斯數由 定義lucas = helper 1 2:
lucas 5 = helper 1 2 5
== helper 3 1 4
== helper 4 3 3
== helper 7 4 2
== helper 11 7 1
( == helper 18 11 0)
== 11
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316836.html
上一篇:在Haskell函式中提取引數
