我正在尝试在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)
你能告诉我如何解决这个问题。谢谢。
答案 0 :(得分:1)
当您在比赛中执行x :: y :: l
时,您将永久有效地取出列表中的元素。
因此,如果您想对元素对进行操作,则需要将其重新放入。
示例:
您有[1;2;3;4]
你想在1和2上操作,在你的比赛中它会解释为:
1 :: 2 :: [3;4]
如果继续而不添加元素,则下一个语句为:
3 :: 4 :: []
这不是你想要的。
要解决此问题,您需要执行(average2 (x'::xs)
,而不仅仅是(average2 xs)
,因为xs
是将元素取出后列表的其余部分。
答案 1 :(得分:1)
OCaml允许使用p
(alias patterns)将模式v
绑定到变量p as v
:
let rec average2 = function
| x :: (y :: _ as tail) -> (x + y) / 2 :: (average2 tail)
| _ -> []
在上方,y :: _ as tail
将名为tail
的列表解构为由y
为首的非空列表,并且具有任意尾_
,其中值为#{1}} 39;关心。
请注意,我还简化了您的功能,以便您不检查_
是否为空:递归在此处理此问题。
此外,如果列表中有零个或一个元素,则应返回一个空列表。
# average2 [ 10; 20; 30; 40];;
- : int list = [15; 25; 35]