2012-02-17 92 views
5
let undefined = ["string"; ""; "string"; "boolean";"";"innermost"] 

我有一個列表,我想寫一個函數,返回一個沒有重複和空字符串列表的列表。例如上面的undefined名單將返回:刪除重複的字符串和空字符串

["string"; "boolean"; "innermost"] 

我寫這篇文章的功能還給我沒有重複的,但我怎麼可以測試一個空字符串添加條件。

let rec uniquify = function 
| [] -> [] 
| x::xs -> x :: uniquify (List.filter ((<>) x) xs) 

非常感謝您

回答

5

只是管結果List.filter (fun s -> s <> "")事後刪除空字符串。這是簡單的,組成的方式,喲ü還可以砍你的功能,或通過轉換爲一組砸默默

let rec uniquify = function 
| [] -> [] 
| x::xs -> 
    (if x = "" then [] else [x]) @ uniquify (List.filter ((<>) x) xs) 

請注意,你的函數是二次的,你可以先排序列表中有更好的複雜性和背部。 Batteries有功能爲你做。

let do_stuff list = 
    let open Batteries in 
    List.remove (List.sort_unique String.compare list) "" 
7

您可以使用一組已經看到的字符串:

module StringSet = Set.Make(String) 
let uniquify list = 
    let rec iter acc set list = 
    match list with 
    | [] -> List.rev acc 
    | s :: tail -> 
     if StringSet.mem s set then 
      iter acc set tail 
     else 
      iter (s :: acc) (StringSet.add s set) tail 
    in 
    iter [] StringSet.empty list 

第一行定義組字符串類型。

然後,uniquify調用一個輔助函數,將一個從未見過的字符串添加到列表和集合中,或者放棄該字符串。 acc用於使迭代尾遞歸(從而避免長列表上的堆棧溢出)。

使用此方案更好,因爲複雜性在O(N.log N)而不是N²。

+0

@ Febrice Le Fessant我試過你的代碼,並且在第8行(iter s set tail)編譯器給了我這個錯誤:Error:「This expression has type StringSet.elt = string but a expectation of type'list 「。 – Quyen 2012-02-18 05:52:18

+1

第8行有一個小錯誤,iter的第一個參數是一個字符串列表,而不僅僅是一個字符串。 我剛剛在[TryOCaml](http://try.ocamlpro.com/)上試過了,現在它工作正常。 – cago 2012-02-18 12:08:05