[英]Is this a good example of tail recursion in F#?
let shuffley (numbers:int list) =
let rec loop numbers acc =
match numbers with
| head::tail -> loop (List.rev(tail)) (head::acc)
| [] -> List.rev(acc)
loop numbers []
shuffley [1;2;3;4;5;6;7;8]
我正在嘗試練習一些 F#,我想知道是否可以作為尾遞歸的一個很好的例子,或者這只是一些廢話。
它是尾遞歸的,但您為輸入列表的每個元素調用一次List.rev
-
shuffley [1;2;3;4;5;6;7;8] = // ...
// numbers acc
loop [1;2;3;4;5;6;7;8] []
loop (List.rev [2;3;4;5;6;7;8]) [1]
loop (List.rev [7;6;5;4;3;2]) [8;1]
loop (List.rev [3;4;5;6;7]) [2;8;1]
loop (List.rev [6;5;4;3]) [7;2;8;1]
loop (List.rev [4;5;6]) [3;7;2;8;1]
loop (List.rev [5;4]) [6;3;7;2;8;1]
loop (List.rev [5]) [4;6;3;7;2;8;1]
loop (List.rev []) [5;4;6;3;7;2;8;1]
List.rev [5;4;6;3;7;2;8;1]
[1;8;2;7;3;6;4;5]
List.rev
是O(n) ,因此隨着輸入的增長, shuffley
的過程呈指數增長。 這是否使它成為 F# 中尾遞歸的一個很好的例子? 可能不會。 對於這個特定的程序,我們只需要反轉輸入一次——
let shuffley l =
let rec loop xx yy zz r =
match xx, yy, zz with
| _::_::xx, y::yy, z::zz -> loop xx yy zz (z::y::r)
| _::xx , y::_ , _ -> List.rev (y::r)
| _ -> List.rev r
loop l l (List.rev l) []
printfn "%A" (shuffley [1;2;3;4;5;6;7;8])
// ...
這個loop
每次迭代匹配兩個xx
並產生一個非常簡單的過程 -
// xx yy zz r
loop [1;2;3;4;5;6;7;8] [1;2;3;4;5;6;7;8] [8;7;6;5;4;3;2;1] []
loop [3;4;5;6;7;8] [2;3;4;5;6;7;8] [7;6;5;4;3;2;1] [8;1]
loop [5;6;7;8] [3;4;5;6;7;8] [6;5;4;3;2;1] [7;2;8;1]
loop [7;8] [4;5;6;7;8] [5;4;3;2;1] [6;3;7;2;8;1]
loop [] [5;6;7;8] [4;3;2;1] [5;4;6;3;7;2;8;1]
List.rev [5;4;6;3;7;2;8;1]
[1;8;2;7;3;6;4;5]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.