【问题标题】:Is this a good example of tail recursion in F#?这是 F# 中尾递归的一个很好的例子吗?
【发布时间】:2016-04-25 16:52:38
【问题描述】:
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#,我想知道是否可以作为尾递归的一个很好的例子,或者这只是一些废话。

【问题讨论】:

  • 这可能属于codereview.stackexchange.com,希望版主可以把它移到那里:-)
  • 也就是说,你的函数是尾递归的——对我来说它是一个很好的例子!
  • 如果您打算将其移至 Code Review,请确保代码不是假设的或损坏的,并且您实际上是在寻找审查,而不仅仅是验证完成。跨度>
  • 如果可行,它肯定会成为代码审查的主题。
  • 虽然它尾递归的,但我认为它非常适合CR,因为它在运行时复杂性方面不是最佳的(因此不是一个好 例子)。

标签: list recursion f# tail-recursion


【解决方案1】:

它是尾递归的,但您对输入列表的每个元素调用一次 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.revO(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]

【讨论】:

    猜你喜欢
    • 2015-10-30
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多