首页 > 解决方案 > 如果包含 x 或 -x,如何修改列表列表?

问题描述

我正在尝试修改具有特定条件的列表列表,如果嵌套列表包含 x,我想从列表中删除该列表,如果嵌套列表包含 -x,我想从中删除 -x该列表,同时仍保留所述列表。最后,如果嵌套列表不包含 x 或 -x,我会保留它。

到目前为止,这是我尝试过的,我真的不明白为什么它不能按预期工作......

let rec simplify i clauses =
  match clauses with
  | [] -> []
  | x::y -> if (List.mem i x) then [] @ simplify i y else if (List.mem (-i) x) then List.filter (fun x -> x != -i) x @ simplify i y else [x];;

预期的结果是:

simplify (-1) [[-1;2];[-1;7];[-2;1];[-2;3];[-3;2];[-3;4];[-4;5];[-4;15];[-5;2];[-5;4];[-6;5];[-7;1];[-7;8];[-7;6];[-8;7];[-8;9];[-8;10];[-9;8];[-10;8];[-10;11];[-10;12];[-11;9];[-11;10];[-12;6];[-12;10];[-12;13];[-12;15];[-13;11];[-14;13];[-14;15];[-15;12];[1];[-14]]
;;
- : int list list =
[[-14]; []; [-15; 12]; [-14; 15]; [-14; 13]; [-13; 11]; [-12; 15]; [-12; 13];
 [-12; 10]; [-12; 6]; [-11; 10]; [-11; 9]; [-10; 12]; [-10; 11]; [-10; 8];
 [-9; 8]; [-8; 10]; [-8; 9]; [-8; 7]; [-7; 6]; [-7; 8]; [-7]; [-6; 5]; 
 [-5; 4]; [-5; 2]; [-4; 15]; [-4; 5]; [-3; 4]; [-3; 2]; [-2; 3]; [-2]]

而实际结果是:

simplifie_aux (-1) [[-1;2];[-1;7];[-2;1];[-2;3];[-3;2];[-3;4];[-4;5];[-4;15];[-5;2];[-5;4];[-6;5];[-7;1];[-7;8];[-7;6];[-8;7];[-8;9];[-8;10];[-9;8];[-10;8];[-10;11];[-10;12];[-11;9];[-11;10];[-12;6];[-12;10];[-12;13];[-12;15];[-13;11];[-14;13];[-14;15];[-15;12];[1];[-14]]
;;
- : int list list = [[-2]; [-2; 3]]

谢谢。

标签: listocamlnested-lists

解决方案


在您的代码中,您似乎也应该在最后else [x]一种情况下进行递归。但是,我会将其重写为fold,因为您正在从预期的输出中删除(一些)空列表,例如。

let simplify i clauses = 
  let f acc lst =
    if List.mem i lst then acc
    else [List.filter (fun x -> x != -i) lst] @ acc
  in List.fold_left f [] clauses

(* - : int list list =
   [[-14]; []; [-15; 12]; [-14; 15]; ... ] *)

推荐阅读