问题
My task is to create a histogram that output the number of times that an element it is in a list.
Input:[2;2;2;3;4;4;1]
Output[(2, 3); (2, 2); (2, 1); (3, 1); (4, 2); (4, 1); (1, 1)]
Expected output : [(2, 3); (3, 1); (4, 2); (1, 1)]
My code:
let rec count a ls = match ls with
|[] -> 0
|x::xs when x=a -> 1 + count a xs
|_::xs -> count a xs
let rec count a = function
|[] -> 0
|x::xs when x=a -> 1 + count a xs
|_::xs -> count a xs
let rec histo l = match l with
|[] -> []
|x :: xs -> [(x, count x l)] @ histo xs ;;
What have i done wrong?
回答1:
The issue is that xs contains potentially elements that are equal to x. This is what you see in your ouput : (2,3) means that there is 3 times 2 in the list; xs is then equals to [2;2;3;4;4;1]... and so on.
Also (not impacting the conclusion): you have 2 definitions of count, but they are identical.
To implement an histogram, use Hashtbl :
let h = Hashtbl.create 1000;;
List.iter (fun x -> let c = try Hashtbl.find h x with Not_found -> 0 in Hashtbl.replace h x (c+1)) your_list;;
Hashtbl.fold (fun x y acc -> (x,y)::acc) h [];;
来源:https://stackoverflow.com/questions/40442527/create-a-histogram-ocaml