5

所以我需要制作一个描述为的函数

invFib :: Integer -> Maybe Integer

它接受一个整数并在斐波那契数列中查找它(如下面的函数所述)

fibs :: [Integer]
fibs = 0:1:(zipWith (+) fibs (tail fibs)) 

并返回数字示例的索引:

invFib 0~>Just 0

invFib 1~>Just 1Just 2

map invFib [54, 55, 56]~>[Nothing,Just 10,Nothing]

invFib (fibs !! 99)~>Just 99

我尝试制作一个接受整数列表并吐出索引的函数,但它一直失败。有什么想法吗?

这是我尝试过的功能-

findNum :: [Integer] -> Integer -> Integer -> Integer
findNum x:xs y z = if x == y
                then z
                else findNum xs y (z+1)

编辑:该函数冻结不在斐波那契数列中的数字,当输入 1 时也只显示 1 个值

invFib :: Integer -> Maybe Integer
invFib n = if n < 0
        then Nothing
        else fmap fromIntegral (elemIndex n fibs)
4

3 回答 3

8

所以这里的关键是它fibs是无限的,但也是单调递增的。因此,一旦它超过了正在寻找的数字,它就可以返回Nothing

findIndexInAscendingList :: (Ord a) => a -> [a] -> Maybe Integer
findIndexInAscendingList a xs = find 0 xs
  where
    find i [] = Nothing -- won't get used for fibs
    find i (x:xs) | a == x    = Just i
                  | a < x     = Nothing
                  | otherwise = find (i + 1) xs

invFib :: Integer -> Maybe Integer
invFib n = findIndexInAscendingList n fibs

所以:

$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
λ: :load Fib.hs 
[1 of 1] Compiling Main             ( Fib.hs, interpreted )
Ok, modules loaded: Main.
λ: map invFib [54,55,56]
[Nothing,Just 10,Nothing]

还有其他一些方法可以做到这一点。考虑一下zip fibs [0..],然后您可以使用dropWhile删除小于的部分n并测试剩下的部分。

于 2013-04-03T06:54:18.077 回答
7

为什么不使用像“takeWhile”这样的函数来返回要检查的无限“fibs”列表的一部分?使用有限列表,您可以应用像“elemIndex”这样的函数,只需稍微调整一下类型,就可以返回您想要的内容。

elemIndex myInteger (takeWhile (<= myInteger) fibs)
于 2013-04-03T04:00:41.283 回答
1

如果您已经计算过fibs,那么答案很简单:

import Data.List

invFib :: Integer -> Maybe Integer
invFib n = fmap fromIntegral (elemIndex n fibs)

fibs :: [Integer]
fibs = 0:1:(zipWith (+) fibs (tail fibs))
于 2013-04-03T02:12:49.187 回答