2016-11-08 45 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個複雜度。我認爲這不是主要觀點;即這是一個學習練習。