交替合并两个列表

时间:2019-10-23 19:26:04

标签: list ocaml

编写一个结合了两个列表的函数。输出列表中的项目将交替显示。您不得使用复杂度大于O(1)的库函数(例如“长度”,“反向”,“追加”)。

我的代码:

let rec zip(aList, bList) list = 
let rec first(aLst, bLst) list = 
    if(aLst = [] && bLst = []) then []
    else if(aLst = []) then second(aLst,bLst)
     else aLst.hd :: second(aLst.tl, bLst)

 let rec second(aLst, bLst) list = 
    if(aLst = [] && bLst = []) then []
    else if(bLst = []) then first(aLst,bLst)
    else bLst.hd :: first(aLst, bLst.tl);;

zip([1;2;3;4;5], [-6]);;
zip([1;2;3;4;5],[]);;
zip([-6],[1;2;3;4;5]);;

问题:

let rec second(aLst, bLst) list =

错误:语法错误

我也担心 rec -它会正常工作吗?

2 个答案:

答案 0 :(得分:0)

常见的交替递归模式是在递归调用中交换参数,例如。

let rec zip a b =
  match a with
  | [] -> b
  | x :: a' -> x :: zip b a'                      (* swap arguments *)

zip [-6;-5;-4] [1;2;3];;
(* - : int list = [-6; 1; -5; 2; -4; 3] *)

答案 1 :(得分:0)

嵌套let的语法是

let v = expr0 in expr

您忘记了in和最后一个expr

let rec zip(aList, bList) list = 
  let rec first(aLst, bLst) list = 
    if(aLst = [] && bLst = []) then []
    else if(aLst = []) then second(aLst,bLst)
     else aLst.hd :: second(aLst.tl, bLst)
  in
  let rec second(aLst, bLst) list = 
    if(aLst = [] && bLst = []) then []
    else if(bLst = []) then first(aLst,bLst)
    else bLst.hd :: first(aLst, bLst.tl)
  in
  first (aLst, bLst)
;;

下一个问题是firstsecond是相互递归的。这需要使用and

let rec zip(aList, bList) list = 
  let rec first(aLst, bLst) list = 
    if(aLst = [] && bLst = []) then []
    else if(aLst = []) then second(aLst,bLst)
     else aLst.hd :: second(aLst.tl, bLst)
  and second(aLst, bLst) list = 
    if(aLst = [] && bLst = []) then []
    else if(bLst = []) then first(aLst,bLst)
    else bLst.hd :: first(aLst, bLst.tl)
  in
  first (aLst, bLst)
;;

接下来(aLst, bLst) list会发生什么?应该存在的“清单”是什么?全面删除这些内容。

最后一个ocaml列表不是对象。 Ocaml有对象,但是方法用#调用。具有标签hd和tl的列表记录也没有。因此aLst.hd没有任何意义。您必须改用List.hd aLst。模式匹配甚至更好,但是您似乎还没有学到。

将所有内容放在一起,您将得到:

let rec zip(aList, bList) = 
  let rec first(aLst, bLst) = 
    if(aLst = [] && bLst = []) then []
    else if(aLst = []) then second(aLst,bLst)
     else List.hd aLst :: second(List.tl aLst, bLst)
  and second(aLst, bLst) = 
    if(aLst = [] && bLst = []) then []
    else if(bLst = []) then first(aLst,bLst)
    else List.hd bLst :: first(aLst, List.tl bLst)
  in
  first (aList, bList)
;;

# zip([1;3;5], [2;4;6]);;
- : int list = [1; 2; 3; 4; 5; 6]