ocaml删除列表中的重复项

时间:2019-02-07 16:50:26

标签: list ocaml

伙计们,我有点麻烦,我对代码应该是什么却有了一个大致的了解,但不确定从这里开始该怎么做。

问题是:定义一个函数remove_elts,该函数接受一个项目列表以及一个要    从第一个列表中删除,并返回包含所有项目的列表    被删除不见了。

我的代码是:

         let remove_elts l reml = 
           match l with
           [] -> false
           | hd :: tl -> if hd = l then reml
             else hd :: remove_elts l tl;;

1 个答案:

答案 0 :(得分:1)

任何过滤功能,即获取一个容器并返回另一个包含满足某些属性的输入容器元素的容器的函数,都是使用以下算法实现的:

output-sequence = []
foreach element in the input-sequeunce:
   if element satisfies condition:
      output-sequence := output-sequence + element

此迭代有两个元素,每个元素各不相同,element变量按input-sequence的元素顺序排列,输出序列每次增长,<element>满足条件。

在函数式编程中,迭代通常用递归表示,从数学的角度来看,递归更为自然。迭代中的任何更改都将成为递归函数的参数,并且每个步骤都表示为具有变量新值的递归调用。因此,功能样式(伪代码)中的相同迭代

filter input-sequence output-sequence =
  if is-empty input-sequence then output-sequence
  else 
      let element = first-element-of input-sequence in
      let rest = drop-first-element input-sequence in
      if element satisfies condition 
      then filter rest (output-sequence + element)
      else filter rest output-sequence

迭代称为

filter input-sequence []

因此,它比foreach更加冗长,但这是因为foreach基本上是语法糖。

现在,您的任务是在OCaml中实现此操作,同时牢记两件事:

1)在OCaml中,您可以使用模式匹配来代替is-emptyfirst-element-ofdrop-first-element原语。

2)您正在使用一个单链列表作为序列,因此将元素附加到它的末尾非常昂贵,它是O(N)(因为您必须遍历所有元素,直到到达结束),然后循环执行此操作会使您的算法变为O(N ^ 2),因此您应该将其放在开头(即O(1)),并在递归结束时反转列表。