如何使用fold_left在OCaml中找到列表中第二小的数字?

时间:2013-09-19 00:02:57

标签: ocaml minimum folding

到目前为止,我有一个小代码片段,用于搜索列表中的最小值

let sec_small lst=
let min_helper min curr =
    if (min < curr) then min else curr
in List.fold_left min_helper (List.hd lst) lst

这是一些返回列表最小值的代码。我只是想知道,我应该如何继续制作它以便我可以寻找列表中的第二个最小元素?

3 个答案:

答案 0 :(得分:2)

不记得一个号码,还记得其中两个吗?

(顺便说一句,当你做这样的事情时,代码会变得非常复杂。这可能就是练习的重点。如果你想要第三个最小的数字,你几乎只需要对列表进行排序并完成它。)

答案 1 :(得分:1)

如果你有一些预循环代码来为折叠工作建立一个不错的不变量,这会更容易。在这种情况下,很明显你想要的是到目前为止看到的有序的一对最小和第二小元素。匹配就这么简单:

let second_smallest list =
  match list with
   | [] | [_] -> failwith "no second element to return"
   | a::b::rest ->
       snd (List.fold_left
              (fun ((sm, ssm) as same) elt ->
                if elt < ssm then
                  if elt < sm then elt, sm else sm, elt
                else same)
              (if a < b then a, b else b, a)
              rest)

答案 2 :(得分:0)

为什么不对你第一次获得的min项进行List.drop,然后再次调用你的sec_small函数?所以,用lst调用sec_small函数一次,我有一个带有sec_small作为其内部函数的外部函数,然后将其称为

(sec_small (List.drop (lst, sec_small lst)))