假设我们有两个列表,[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]]。
感谢。
答案 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