【问题标题】:Average calculating of consecutive list elements in OCamlOCaml中连续列表元素的平均计算
【发布时间】:2016-10-22 23:33:36
【问题描述】:

我正在尝试在 OCaml 中编写一个函数来计算列表中连续元素的平均值。例如[1; 2; 3; 4] 它应该输出[1; 2; 3]。它应该采用(1 + 2) / 2 并给出1 然后采用(2 + 3) / 2 并给出2 等等。 然而,我写的代码只返回[1; 2]

let rec average2 xs = match xs with
|[] -> []
|x :: [] -> [x]
|x :: x' :: xs -> if xs = [] then [(x + x') / 2] else [(x + x') / 2] @ (average2 xs)

你能告诉我如何解决这个问题吗?谢谢。

【问题讨论】:

    标签: recursion ocaml average


    【解决方案1】:

    当您在比赛中使用x :: y :: l 时,您实际上是在永久删除列表中的元素。 因此,如果您想对成对的元素进行操作,则需要放回其中一个。

    例子:

    你有一个[1;2;3;4]的列表

    你想对1和2进行操作,在你的比赛中它会解释为:

    1 :: 2 :: [3;4]
    

    如果不添加元素继续,下一条语句将是:

    3 :: 4 :: []
    

    这不是你想要的。

    要纠正这个问题,在你的递归调用中你需要做(average2 (x'::xs) 而不仅仅是(average2 xs) 因为xs 是取出元素后列表的其余部分。

    【讨论】:

      【解决方案2】:

      OCaml 允许使用 p as v (alias patterns) 将模式 p 绑定到变量 v

      let rec average2 = function
      | x :: (y :: _ as tail) -> (x + y) / 2 :: (average2 tail)
      | _ -> []
      

      在上面,y :: _ as tail 将名为tail 的列表解构为一个以y 为首的非空列表,并具有任意尾部_,我们不关心它的值。 请注意,我还简化了您的函数,这样您就不会检查 _ 是否为空:递归在这里为您处理。 此外,当列表中有零个或一个元素时,您应该返回一个空列表。

      # average2 [ 10; 20; 30; 40];;
      - : int list = [15; 25; 35]
      

      【讨论】:

        猜你喜欢
        • 2017-12-26
        • 1970-01-01
        • 1970-01-01
        • 2019-08-01
        • 2018-03-19
        • 2018-06-21
        • 2013-06-07
        • 1970-01-01
        • 2015-12-01
        相关资源
        最近更新 更多