2016-11-08 41 views
0

从列表示例[“狗”;“猫”;“狗”;“猫”;“狗”]我必须找到一个单词产生的时间数这个清单 结果 - > [(“dog”,3);(“cat”,2)] 但我得到一个奇怪的结果:[(“dog”,1); (“猫”,1); (“狗”,2); (“猫”,2); ( “狗”,3)]Ocaml - 查找列表中的字数

我的代码是这样的:

let rec nuovaParola par l = 
match l with 
[] -> true 
|(a,_)::z ->if (par=a) then false 
      else nuovaParola par (List.tl l);; 

let rec contaParole par l = 
let rec contatore par l cont = 
    match l with 
    [] -> (par, cont) 
    |x::y -> if(par=x) then contatore par y (cont+1) 
      else contatore par y cont 
in contatore par l 0;; 

let rec occorrenze l = 
let rec aux l l1= 
match l with 
    [] -> l1 
    |x::y -> if (nuovaParola x l1) then aux y [email protected][(contaParole x l)] 
      else aux y l1 
in aux l [];;` 

nuovaParola给我true,如果字是不是里面别的名单给我假的。

contaParola用(“单词”,数字)重新激活元组;

Occorrenze是主要功能。我没有发现问题! 感谢您的帮助!

+2

[创建直方图OCaml]的可能副本(http://stackoverflow.com/questions/40442527/create-a-histogram-ocaml) – coredump

回答

1

事实上,你有和前面引用的StackOverflow页面一样的问题。您将为每个找到的单词添加一个新元素。这不起作用,因为您希望每个唯一字的输出中只有一个元素。

实际上,您需要更新列表中的现有条目,而不是添加新条目。

但是,OCaml中的列表是不可变的。您实际上无法更新列表,只能使用所需内容创建一个新列表。

这里是一个函数,用于更新非负整数列表:它将每个元素四舍五入到下一个偶数。

let rec upeven l = 
    match l with 
    | [] -> [] 
    | h :: t -> 
     let h' = if h mod 2 = 1 then h + 1 else h in 
     h' :: upeven t 

关键的一点是,此功能不会修改列表l,它会创建根据需要被修改的新列表。

这与您的问题类似,除了您正在寻找与您的单词相匹配的元素,而不是奇数。

作为一个方面的评论,使用列表来存储您的计数是不是一个特别可扩展的解决方案。如果您的输入列表可能很大,那么最好使用日志复杂度较高的东西,比如Map。通过列表可以看到线性复杂性,因此总体上可以获得n^2个复杂度。我认为这不是主要观点;即这是一个学习练习。