如何在OCAML中编写函数,该函数返回一个列表,第二个列表插入第一个列表中

时间:2019-04-12 20:54:45

标签: ocaml

如何编写一个包含两个列表和一个整数的函数 (例如:int n)作为输入,然后返回将第二个列表插入到第一个列表中的第二个列表到第n个位置(这就是函数也将INT作为输入的原因)。

这是我已经做过的事情,但是我似乎对类型为“ prev”的“可变变量” list1”有疑问,我不确定是否甚至将其称为“ prev”函数代码应该可以,但是编译器给我这个错误:

第12行,字符18-22: 错误:此记录模式应具有类型列表        上一个字段不属于类型列表

编译器为我提供的“ prev”可变变量的错误基本上只是语法错误。

type list = {
    value : int;
    mutable next : list1
    mutable prev : list1
    }

  and list1 = 
  Empty
  | Node of list ;;

let rec insert sez x = match sez with Empty -> Node {value=x; prev=Empty; 
  next=Empty}
  | Node {value=r; prev=lb; next=rb} -> 
    if x < r then Node {value=r; prev=(insert lb x); next=rb} 
    else Node {value=r; prev=lb; next=(insert rb x)};;

1 个答案:

答案 0 :(得分:0)

假设我们有两个列表-L1L2-并将位置k插入前一个,简单的算法如下所示:

  1. 创建一个由L1的前k个元素组成的列表(将其命名为prefix
  2. 创建一个由其余L1个元素组成的列表(将其命名为postfix
  3. Concat prefixL2postfix

前缀和后缀列表可以描述为“先获取k个元素”和“删除前k个元素并获取其余元素”-听起来很熟悉,对吗?因此,我们可以从以下辅助功能开始:

let rec take k lst =
  match k with
    | 0 -> []
    | k -> (match lst with
      | [] -> failwith "too short"
      | h::t -> h :: (take (k - 1) t))

let rec drop k lst =
  match k with
    | 0 -> lst
    | k -> (match lst with
      | [] -> failwith "too short"
      | h::t -> drop (k-1) t)

现在解决方案变得非常简单:

let insert l1 l2 n =
  match n with
    | 0 -> l2 @ l1
    | n ->
      if n = List.length l1 then l1 @ l2
      else (take n l1) @ l2 @ (drop n l1)

(由于级联,效率不高,但很简单)

UPD。实际上,insert本身可能就像

let insert l1 l2 n =
  (take n l1) @ l2 @ (drop n l1)