简体   繁体   中英

merge (int * string) list ocaml

I have this function:

let encode list =
let rec aux count acc = function
 | [] -> [] (* Caso a lista esteja vazia*)
 | [x] -> (count+1, x) :: acc
 | a :: (b :: _ as t) -> 
    if a = b then aux (count + 1) acc t
            else aux 0 ((count+1,a) :: acc) t in
        List.rev (aux 0 [] list)
;;

and with this input:

let test = encode ["a";"a";"a";"a";"b";"f";"f";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;

And i have this Output:

val test : (int * string) list =
[(4, "a"); (1, "b"); (2, "f"); (2, "c"); (2, "a"); (1, "d"); (4, "e")]

but the "a" is a repeated and "f" need to be at final! I need a output like:

val test : (int * string) list =
[(6, "a"); (1, "b"); (2, "c"); (1, "d"); (4, "e"); (2, "f")]

Can anybody help, please?! Thanks!

You are counting repeated adjacent values, so-called run-length encoding. It appears you want to count occurrences across the whole input. You can either sort the input beforehand, or you can use a more complicated data structure (such as a Map) to keep track of your counts.

Something like this:

let encode xs = 
  let f acc x = 
    let n = try M.find x acc  with Not_found -> 0 in 
    M.add x (n+1) acc in
  let ans = (List.fold_left f M.empty) xs in 
  M.bindings ans ;;

# encode ["a";"a";"a";"a";"b";"f";"f";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;
- : (M.key * int) list =
[("a", 6); ("b", 1); ("c", 2); ("d", 1); ("e", 4); ("f", 2)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM