2012-04-22 73 views
0

这里是2个函数计算fibbonaci号,它们都正常工作,但都写在以不同的方式。F#fibbonaci高效的算法

哪一个你会考虑更好,更有效,代码更易懂?

let fibe n = 
    let rec loop acc1 acc2 n = 
     match n with 
     | n when n = 0I -> acc1   
     | x -> loop acc2 (acc1 + acc2) (x - 1I) 
    loop 0I 1I n 

let myfib n = 
    if n = 0I then 0I 
    else if n = 1I then 1I 
    else 
    let rec loop i f s = 
     match i with 
     | x when x = n -> f+s 
     | x when x < n -> loop (i+1I) s (s+f)   
    loop 2I 0I 1I 
+0

http://codereview.stackexchange.com/ – tvanfosson 2012-04-22 13:16:21

回答

1

谈到清晰度,IMO的这两项功能都是不必要的混乱,并且为此目的使用不充分的语言机制。

生成斐波那契数是通过unfold表达的理想人选,象下面这样:

let fibnum n = 
    let fibnums = Seq.unfold (fun (current, next) -> 
       Some(current, (next, current+next)))(0I,1I) 
    fibnums |> Seq.nth n 

你可以如何使它更短,更清晰?

UPDATE:作为问题的作者认为,与具有序列号斐波纳契成员工作的能力bigint重要的是,上面的代码中绝对可以采用这一要求,虽然越来越少直截了当:

let fibnum bigN = 
    let fibnumsI = 
     ((0I,0I),(1I,0I)) 
     |> Seq.unfold (fun ((current, idx), (next, idx)) -> 
      Some((current, idx),((next, idx + 1I), (current+next, idx + 1I)))) 
    fibnumsI |> Seq.skipWhile (fun (x,i) -> i < bigN) |> Seq.head |> fst 
+0

不能编译,(N-1I),它要求1,而不是1I – Omu 2012-04-22 13:36:40

+0

对不起,现在就试试,我的坏习惯没有计算机编写代码:(。 – 2012-04-22 13:37:48

+0

这样,仅适用于整数,不适用于bigint – Omu 2012-04-22 13:39:46