伙计们,我有点麻烦,我对代码应该是什么却有了一个大致的了解,但不确定从这里开始该怎么做。
问题是:定义一个函数remove_elts,该函数接受一个项目列表以及一个要 从第一个列表中删除,并返回包含所有项目的列表 被删除不见了。
我的代码是:
let remove_elts l reml =
match l with
[] -> false
| hd :: tl -> if hd = l then reml
else hd :: remove_elts l tl;;
答案 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-empty
,first-element-of
和drop-first-element
原语。
2)您正在使用一个单链列表作为序列,因此将元素附加到它的末尾非常昂贵,它是O(N)(因为您必须遍历所有元素,直到到达结束),然后循环执行此操作会使您的算法变为O(N ^ 2),因此您应该将其放在开头(即O(1)),并在递归结束时反转列表。