假设我有一个清单:
[1; 3; 4; 2; 1; 5; 1]
我需要编写一个函数来返回最常出现的数字,在这种情况下输出应该是
int:1
有什么想法吗? 这是我到目前为止所做的,但它似乎并没有做任何事情,真的!
让rec r ls =与ls匹配
| [] - > 0
| hd :: tl - > if(hd ==(r tl))则1 + r tl else r tl;
答案 0 :(得分:6)
您可以为每个数字构建列表中显示的次数。这可以通过列表的单次遍历来构建。
答案 1 :(得分:4)
对列表进行排序。编写一个尾递归函数,其累加器包含:
None
0
,1
最初。调用函数传递初始累加器和排序列表的尾部。
答案 2 :(得分:2)
如果您将相同的元素与排序结合在一起并设置一个漂亮的循环不变量,这非常简单。我们的想法是扫描相同元素的运行,在每次运行结束时测试它是否是迄今为止最长的。
让它变得简单的技巧是进行预循环匹配以获得循环边缘情况(空列表)。
let most_frequent_elt list =
let rec loop maxelt maxcount elt count = function
| [] -> if count > maxcount then elt else maxelt
| x::xs ->
if elt = x then loop maxelt maxcount elt (count + 1) xs
else if count > maxcount then loop elt count x 1 xs
else loop maxelt maxcount x 1 xs in
match List.sort compare list with
| [] -> None
| x::xs -> Some (loop x 0 x 1 xs)
答案 3 :(得分:0)
基本上实施lukstafi的答案(使用可变字段):
type 'a accumulator = { mutable curr: 'a option; mutable cnt: int;
mutable el: 'a option; mutable max: int; }
let rec process acc = function
| [] -> acc.el
| hd::tl ->
if Some(hd) = acc.curr then begin
acc.cnt <- (acc.cnt + 1);
if acc.cnt > acc.max then
acc.max <- acc.cnt;
acc.el <- Some(hd)
end
else begin
acc.cnt <- 1;
acc.curr <- Some hd
end;
process acc tl
let option2string = function | None -> "" | Some v -> string_of_int v
let () =
let sorted = List.sort compare [1;3;4;2;1;5;1] in
let init = { curr = None; cnt = 0; el = None; max = 0 } in
print_endline (option2string (process init sorted))
答案 4 :(得分:0)
最新答案,但根据count unique elements in list in OCaml的基准,使用Hashtbl
可以取得良好的性能。
然后,对元素及其出现次数进行简单排序,即可获得列表中最常见的元素。
module IntHash =
struct
type t = int
let equal i j = i=j
let hash i = i land max_int
end
module IntHashtbl = Hashtbl.Make(IntHash)
let count_unique_elements_int_hashtbl list =
let counter = IntHashtbl.create 10000 in
let update_counter x =
if IntHashtbl.mem counter x then
let current_count = IntHashtbl.find counter x in
IntHashtbl.replace counter x (succ current_count)
else
IntHashtbl.replace counter x 1
in
List.iter update_counter list;
IntHashtbl.to_seq counter
|> List.of_seq
let most_common_element_in_int_list list =
count_unique_elements_int_hashtbl list
|> List.sort (fun x y -> compare (snd x) (snd y))
|> List.rev
|> List.hd
|> fst
let () =
assert (most_common_element_in_int_list [1;2;1] = 1);
assert (most_common_element_in_int_list [6;1;2;1;6;6] = 6);