在Haskell中的斐波那契数列

3

大家好,我需要将我的F#代码转换为Haskell代码,但我对Haskell非常陌生,不知道该怎么做。我的代码简单地从键盘读取数据,如果数据不是整数,则返回错误消息,然后计算n个斐波那契数,将它们写入一个列表,最后将列表写入一个文本文件。以下是我的代码:

open System
let rec fib n = 
    match n with
    |0->0
    |1->1
    |2->1
    |n->fib(n-1)+fib(n-2);;

let printFibonacci list = 
    for i=0 to (List.length list)-1 do
        printf "%d " (list.Item(i));;

let writeToFile list = 
    let file = System.IO.File.Create("C:\out2.txt")
    let mutable s =""
    let writer = new System.IO.StreamWriter(file)
    try
        for i=0 to (List.length list)-1 do
        s <- list.Item(i).ToString()
        writer.Write(s+" ")

    finally
        writer.Close()
        file.Dispose()
        printfn "Writed To File"


let mutable control = true
let mutable num = 0
while control do 
    try
    printfn "Enter a Number:" 

    num <- Convert.ToInt32(stdin.ReadLine()) 
    let listFibonacci = [for i in 0 .. num-1->fib(i)]
    printFibonacci(listFibonacci)
    printfn "\n%A"(listFibonacci)
    writeToFile(listFibonacci)
    control<-false
    with
        | :? System.FormatException->printfn "Number Format Exception";

Console.ReadKey true|>ignore

1
这里已经很好地涵盖了:https://dev59.com/HHNA5IYBdhLWcg3wEZeT - JeffH
1
谷歌会给你Haskell维基页面:http://www.haskell.org/haskellwiki/The_Fibonacci_sequence,详细介绍了这个问题。 - Don Stewart
2个回答

15
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = do putStrLn "Enter a number:"
          num <- readLn
          fibs = map fib [0..n]
          mapM' print fibs

然而,由于Haskell是惰性的,有一种聪明的方法来定义所有斐波那契数列的列表。而且,既然你想要该列表的前缀,使用这个定义更自然(也更有效):

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

main = do putStrLn "Enter a number:"
          num <- readLn
          mapM' print (take n fibs)

编辑:如果要将内容写入文件而不是标准输出,请将print替换为(\num -> appendFile "filename" (show num))(appendFile "filename" . show)


2
那基本上就是序列最常见的实现方式:
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

如果你想从键盘上获取数字:

main :: IO ()
main = catch doFib handle
   where doFib = do
            num <- readLn
            putStrLn $ "Fib of " ++ show num ++ " = " ++ (show . fib $ num)
         handle _ -> putStrLn "Malformed input!"

完成!


你真的推荐一个时间复杂度为O(2^n)的算法吗?除了n很小的情况下,它会非常慢。 - Yacoby
3
不建议使用!只是说这是最基本且(在这里最重要的是,因为他对Haskell不熟悉!)最简单的实现方式。 - LukeN
4
@Yacoby:这是 OP 算法在 F# 中实现的精确翻译,因此它是一种翻译,而不是建议。 - yairchu
@LukeN,使用你的代码时,我遇到了“错误:输入`->'解析错误”的问题。我是FP新手,很抱歉。 - Jake Muller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接