我对Haskell很新。问题是找到所有偶数Fibonacci数不超过4百万的总和。我不能使用列表。
如果我理解正确,下面的解决方案是错误的,因为它使用列表:
my_sum = sum $ filter (odd) $ takeWhile (< 4000000) fibs
其中 fibs 是所有Fibonacci数字的列表。
不知何故,我发现很难不在Haskell中考虑列表。任何人都可以指导我解决这个问题吗?
此致
编辑:
如果有人有兴趣,我已经解决了这个问题。这是代码(非常笨拙,但仍然有效):
findsum threshold = findsum' 0 1 0 threshold
findsum' n1 n2 accu t
| n2 > t = accu
| odd n2 = findsum' n2 n3 accu t
| otherwise = findsum' n2 n3 accu2 t
where
n3 = n2 + n1
accu2 = accu + n2
答案 0 :(得分:5)
您可能会发现在excel中构建它更容易,然后从那里找出代码。在excel中很容易做到这一点。只需将1放在第一个单元格中,然后将1放在它下面。然后让下面的每个单元格添加上面的两个单元格。 (即,单元格a3包含= A1 + A2)。使下一列仅包含偶数值“ie,if(mod(a3,2)== 0,a3,0)”。接下来,将您的运行总和放在第三列中。基于此,您应该能够提出递归解决方案。
另一种方法是从问题开始。你只想要一个为累加器尖叫的总数。
sumFib :: Integer -> Integer
sumFib threshold = sumFib' 1 1 0 threshold
sumFib' :: Integer -> Integer -> Integer -> Integer -> Integer
sumFib' n1 n2 acc threshold
您可以在上面看到我的功能的签名。我建立了一个漂亮的前端,需要一个阈值(4,000,000)来决定何时退出建立斐波那契数字。然后我把这个加上前2个斐波纳契数和一个累加器传递给工作函数“sumFib”,它执行递归。瞧...答案,“4613732”,没有清单......
n1是n-1斐波那契数,n2是n-2斐波纳契数。
希望有所帮助。
编辑:这是我的完整解决方案:
sumFib :: Integer -> Integer
sumFib threshold = sumFib' 1 1 0 threshold
sumFib' :: Integer -> Integer -> Integer -> Integer -> Integer
sumFib' n1 n2 acc threshold
| n1 > threshold = acc
| otherwise = sumFib' (n2+n1) n1 newAcc threshold
where newAcc = if n1 `mod` 2 == 0
then n1 + acc
else acc
答案 1 :(得分:3)
您可以使用continuation-passing style在没有列表的情况下使用递归解决方案执行此操作。
BTW运行所有斐波那契数并过滤掉奇数数字是解决这个问题的缓慢方法。
答案 2 :(得分:3)
同样,计算机有用程度的非示例:
你可以在没有电脑的情况下完成这项工作!
第一次观察:每三个Fibo数是偶数,第一个甚至Fibo数是F_3 = 2
确实:奇数+奇数=偶数;奇数偶数+ =奇数;偶数+奇数=奇数,已经关闭了圆圈
第二次观察:F_3 + F_6 + F_9 + ... + F_ {3k} = 1/2(F_ {3k + 2} - 1)
归纳:F_3 = 2 = 1/2(5 - 1)= 1/2(F_5 - 1)
F_3 + F_6 + ... + F_ {3k + 3} = 1/2(F_ {3k + 2} - 1)+ F_ {3k + 3} = 1/2(F_ {3k + 2} + 2F_ {3k + 3} -1)= 1/2(F_ {3k + 4} + F_ {3k + 3} -1)= 1/2(F_ {3k + 5} -1)
第3次观察:总和将有1333333个加数,最后一个是第3999999个Fibo数。
第4次观察:F_n = 1 / sqrt(5)*(phi ^ n - (1-phi)^ n)
现在,我们可以把各个部分放在一起: F_3 + F_6 + ... + F_3999999 = 1/2(F_4000001 - 1)= 1/2 1 / sqrt(5)(phi ^ 4000001 - (1-phi)^ 4000001) - 1/2 = int(1 / 2 1 / sqrt(5)phi ^ 4000001)
这里int是整数部分。最后一步是有效的,因为-1&lt; 1-phi&lt; 0等(1-phi)^ 4000001几乎消失。您可能希望使用计算器来获取数值。