2

我正在尝试过滤包含斐波那契数的列表。

我需要的只是奇数,并且小于或等于N.

这是我到目前为止所拥有的:

fib   n | n == 0         = 0
        | n == 1         = 1
        | otherwise = fib (n-1) + fib (n-2)

fibs n = [a | a <- [fib x | x <- [1..]], odd a, a < n]

这会给我我想要的东西,但同时该解决方案将不起作用,因为我不知道如何停止fib从函数中检索元素。当然,那是因为x <- [1..]

我想过两个选择:

  1. 放置一个限制(取决于nx <- [1..]
  2. 定义fibs递归,这样我就可以知道何时停止(在写问题时考虑过)

我怎么能这样做?

我不是在寻找有效的方法

编辑:
这是我最后的两个解决方案:

fib   n | n == 0         = 0
        | n == 1         = 1
        | otherwise = fib (n-1) + fib (n-2)

fibsAux n k xs  | a < n     = fibsAux n (k+1) (xs ++ [a])
                | otherwise = xs
                where 
                    a = fib k
fibs n = filter odd $ fibsAux n 0 []

以及使用@hammar 建议的人:

fibs x = takeWhile (< x) [a | a <- [fib x | x <- [1..]], odd n]
4

2 回答 2

6

查看 Data.List 中takeWhile函数(并由 Prelude 重新导出)。例如,

takeWhile (< 4) [1..] == [1, 2, 3]

请注意,即使列表是无限的,一旦找到不满足谓词的元素,它就会终止。

于 2011-05-04T06:30:52.180 回答
6

还有一种更有效的方法来计算斐波那契数:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

可以过滤以仅给出奇数:

oddFibs = filter odd fibs

可以截断为小于或等于 N:

oddFibsLeN n = takeWhile (<= n) oddFibs
于 2011-05-04T07:05:11.743 回答