在OCaml中获取两个列表之间的距离

时间:2015-07-27 22:55:49

标签: ocaml

假设我们有两个列表,[3; 4; 5]和[1; 2; 3],我怎么能得到12的距离,这是通过从第一个列表中减去第二个列表得到的和平方。所以(3-1)^ 2 +(4-2)^ 2 +(5-3)^ 2。我现在有这个想法:

List.map (List.map (fun x -> x*x)) [[1; 2]; [2; 3]];;

但是我怎样才能将它们减去并一起添加呢?以上序列仅返回[[1; 4]; [4; 9]]。

感谢。

4 个答案:

答案 0 :(得分:2)

List.map的结果是一个列表,因此您必须将其减少为整数。 使用库执行此操作的简单方法是使用List.fold_left。

# let distance a b = List.fold_left (fun s -> fun x -> s + x * x) 0 (List.map2 (-) a  b);;
val distance : int list -> int list -> int = <fun>
# distance [3; 4; 5] [1; 2; 3];;
- : int = 12

确保列表的长度相等,否则List.map2会引发异常。

# distance [3; 4] [1; 2; 3];;
Exception: Invalid_argument "List.map2".

答案 1 :(得分:1)

Integer exponentiation in OCaml

借用此整数取幂函数
let rec pow a = function
  | 0 -> 1
  | 1 -> a
  | n ->
    let b = pow a (n / 2) in
    b * b * (if n mod 2 = 0 then 1 else a)

let rec distance l r =
  match l, r with
  | a_val_l :: rest_l, a_val_r :: rest_r -> pow (a_val_l - a_val_r) 2 + distance rest_l rest_r
  | _ -> 0

你的例子:

utop[58]> distance [3;4;5] [1;2;3];;
- : int = 12

答案 2 :(得分:0)

您可以折叠2个以上的列表:

let distance = List.fold_left2 (fun s x y -> s + (x - y) * (x - y)) 0

答案 3 :(得分:0)

获得差异:

let difs = List.map2 (fun a b -> a - b) [3;4;5] [1;2;3]

解决这些问题:

let difs' = List.map (fun x -> x * x) difs

得到结果总和:

let res = List.fold_left (+) 0 difs'

作为一项功能:

let list_dist l1 l2 =
  List.map2 (fun a b -> a - b) l1 l2
  |> List.map (fun x -> x * x)
  |> List.fold_left (+) 0