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

Tengo una lista y deseo escribir una función que devuelva una lista sin duplicados y una lista de cadenas vacía. Por ejemplo, la lista de undefined anterior devolverá:eliminar la cadena duplicada y la cadena vacía

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

escribo esta función devuélvalo para mí sin duplicado pero ¿cómo puedo añadir la condición de prueba con una cadena vacía.

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

Muchas gracias

Respuesta

5

Sólo tubería el resultado de List.filter (fun s -> s <> "") para eliminar la cadena vacía después. Esa es la forma más sencilla, la composición, u yo también podría cortar su función para dejarla caer en silencio

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

en cuenta que su función es cuadrática, que puede tener mejor la complejidad de la clasificación de la primera lista, o mediante la conversión a un conjunto y espalda. Batteries tiene funciones para hacer eso por usted.

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

Se puede utilizar un conjunto de cadenas ya vistos:

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 

La primera línea define el tipo de juego de cuerdas.

Luego, uniquify llama a una función auxiliar para agregar una cadena nunca vista tanto a la lista como al conjunto, o simplemente descartar la cadena. El acc se utiliza para hacer que la iteración sea recursiva (y así evitar desbordamientos de pila en largas listas).

Usar este esquema es mejor ya que la complejidad está en O (N.log N) en lugar de N².

+0

@Febrice Le Fessant Probé tu código y en la línea 8 (iter s set tail) el compilador me dio este error: Error: "Esta expresión tiene type StringSet.elt = string pero se esperaba una expresión de tipo 'a list " – Quyen

+1

Hubo un pequeño error en la línea 8, el primer argumento de iter es una lista de cadenas y no solo una cadena. Acabo de probarlo en [TryOCaml] (http://try.ocamlpro.com/) y funciona bien ahora. – cago