如果我们假设我们从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;;
但现在我被卡住了。
答案 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]]