在Ocaml中列出逆转

时间:2014-01-22 15:11:15

标签: ocaml

如果我们假设我们从0计算元素,如何反转列表的子列表。我希望解决方案是“手动编码”。这个任务我遇到了很大的问题。

例如:

Function([[1;2;3] ; [2;3] ; [1;2;3] ; [5;6;7]])

返回:

([[3;2;1] ; [2;3] ; [3;2;1] ; [5;6;7]])

我已经创建了一个反转单个列表的函数:

let rev =
  let rec rev_append acc l =
    match l with
      [] -> acc
    | h::t -> rev_append (h::acc) t in
  fun l -> rev_append [] l;;

但现在我被卡住了。

3 个答案:

答案 0 :(得分:3)

let rec todo l = let rec aux r = function
       | [] -> []
       | h::t -> (if r then h else rev h)::(aux (not r) t)
in aux true l;;

答案 1 :(得分:1)

let rev_list l =
  let rec rev_acc acc = function
    | [] -> acc
    | hd::tl -> rev_acc (hd::acc) tl
  in 
  rev_acc [] l

let rev_even l = 
  let rec rev i acc = function
    | [] -> rev_list acc
    | hd::tl ->
      if i mod 2 = 0 then rev (i+1) ((rev_list hd)::acc) tl
      else rev (i+1) (hd::acc) tl
  in 
  rev 0 [] l

请注意,它们都是尾递归

修改

对Noran的建议:

尾递归在函数式编程和OCaml中非常重要。请记住。

答案 2 :(得分:1)

为了好玩,我做过这样的事情,

let rev_at_even_idx list = 
  let s0, s1 = ([], 0), [] in
  let aux0 (a, i) x = 
    (x, i mod 2) :: a, succ i 
  in
  let aux1 a = function 
    | l, 0 -> List.rev l :: a 
    | l, _ -> l :: a 
  in 
  List.fold_left aux1 s1 
  @@ fst @@ 
  List.fold_left aux0 s0 list
;;

rev_at_even_idx [[1;2;3] ; [2;3] ; [1;2;3] ; [5;6;7]];;  
- : int list list = [[3; 2; 1]; [2; 3]; [3; 2; 1]; [5; 6; 7]]