如何在OCaml列表中搜索重复的内容?

时间:2015-12-02 11:04:49

标签: ocaml

我有一个这样的清单:

let myList = [(1,2,1);(5,1,4);(10,2,8);(6,0,4)];;

我想要一个在第三个位置返回true的函数,其他第三个位置已存在值。在此示例中(5,1, 4 );(6,0, 4 )。 - 搜索重复 -

谢谢

2 个答案:

答案 0 :(得分:2)

搜索重复项时有两种方法:

  • 对列表进行排序并比较后续元素(O(nlg(n)
  • 使用辅助结构(占用更多内存)

一种对列表进行排序的方法:

# let dup_exists l =
  let rec dup_consecutive = function
    | [] | [_] -> false
    | (_ ,_ ,e1)::((_ ,_ ,e2) as h2)::tl -> e1 = e2 || dup_consecutive (h2::tl)
  in
  let sort_on_third (_, _, e1) (_, _, e2) = compare e1 e2 in
    dup_consecutive (List.sort sort_on_third l);;
val dup_exists : ('a * 'b * 'c) list -> bool = <fun>

# let myList = [(1,2,1);(5,1,4);(10,2,8);(6,0,4)];;
val myList : (int * int * int) list =
  [(1, 2, 1); (5, 1, 4); (10, 2, 8); (6, 0, 4)]
# dup_exists myList;;
- : bool = true
# let myList = [(1,2,1);(5,1,4);(10,2,8);(6,0,10)];;
val myList : (int * int * int) list =
  [(1, 2, 1); (5, 1, 4); (10, 2, 8); (6, 0, 10)]
# dup_exists myList;;
- : bool = false

答案 1 :(得分:1)

另一种方法是使用哈希表来标记访问过的元素。一旦找到重复,返回true。否则,返回false。

exception Found;

let has_dup list =
  let hash = Hashtbl.create (List.length list) in
  try
    begin
      List.iter (function (_,_,x) ->
                  if (Hashtbl.mem hash x)
                  then (raise Found)
                  else (Hashtbl.add hash x true))
                list;
      false
    end
  with Found -> true ;;

构建哈希表时,实际上并不需要计算列表的长度。该部分可能被常量替换(哈希表将增长)。