0

フィボナッチ数を計算する 2 つの関数を次に示します。どちらも正しく機能しますが、別の方法で記述されています。

どちらがより良く、より効率的で、コードがより理解しやすいと思いますか?

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
4

1 に答える 1

1

明確さについて言えば、IMO の両方の関数が不必要に雑然としていて、目的のために不適切な言語メカニズムを使用しています。

unfoldフィボナッチの生成は、以下のようにvia を表現するのに理想的です。

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

どうすればさらに短く、より明確にできますか?

更新: 質問の作成者は、重要なシーケンス番号を持つフィボナッチ メンバーで動作する機能を考慮しているため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
于 2012-04-22T13:19:37.833 に答える