写一个签名函数smallest_absent : int_list -> int
,例如调用smaller_absent l
,返回l
中不存在的最小自然整数
let smallest_absent l =
match l with
|[] -> 0
|_ -> let m = ref (0,false) in
while !m.(1) = false do
if (mem l m.(0)) then !m.(1) := true ;
else incr(m.(0));
done;
!m.(0);;
错误:
> while !m.(1) = false do
this expression is of type int * bool, but is used with the type 'a vect>`
我想知道我的代码有什么问题。如果它在概念上是正确的。谢谢。
答案 0 :(得分:4)
你已经有了答案,所以更像是评论或建议。
也许从概念上讲它是正确的,但它有一个非常复杂的问题,在ocaml程序中看到循环总是很痛苦(特别是在如此简单的程序中)。我建议你在递归方面考虑更多。
使用排序列表(没有重复项)要简单得多,在这种情况下,您只需找到i
的第一个l[i] != i
:
let smallest_absent l =
let l = List.sort_uniq compare l in
let rec f i = function
| [] -> i
| h::t -> if h = i then f (i + 1) t
else i in
f 0 l
你可以想象进一步的优化。
答案 1 :(得分:2)
类型错误说明了一切:您尝试对_.(1)
和int
元组的内容使用向量查找bool
。
您正在寻找的功能是snd : 'a * 'b -> 'b
。
同样,您应该使用fst : 'a * 'b -> 'a
m.(0)
,而不是撰写fst !m
。