Pregunta

Necesito poder escribir una función que muestre palabras repetidas de una cadena y devolver una lista de cadenas en orden de aparición e ignorar las no letras

por ejemplo, en la solicitud de abrazos

repetitions :: String -> [String]

repetitions > "My bag is is action packed packed."
output> ["is","packed"]
repetitions > "My name  name name is Sean ."
output> ["name","name"]
repetitions > "Ade is into into technical drawing drawing ."
output> ["into","drawing"]
¿Fue útil?

Solución

Para dividir una cadena en palabras, use la función words (en el Preludio). Para eliminar caracteres que no sean palabras, filter con Data.Char.isAlphaNum. Comprime la lista junto con su cola para obtener pares adyacentes (x, y). Dobla la lista, creando una nueva lista que contiene todos los x donde y == <=>.

Algo así como:

repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l
  where l = map (filter isAlphaNum) (words s)

No estoy seguro de que funcione, pero debería darte una idea aproximada.

Otros consejos

Soy nuevo en este lenguaje, por lo que mi solución podría ser un poco fea a los ojos de un veterano de Haskell, pero de todos modos:

let repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (words (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') x)))))

Esta parte eliminará todas las letras y espacios que no sean de una cadena s :

filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') s

Este dividirá una cadena s en palabras y agrupará las mismas palabras en listas que devuelven la lista de listas:

List.group (words s)

Cuando esta parte eliminará todas las listas con menos de dos elementos:

filter (\x -> (length x) > 1) s

Después de lo que concatenaremos todas las listas a una eliminando un elemento de ellas

concat (map tail s)

Esto podría no ser eficaz, sin embargo, conceptualmente es muy simple. Supongo que está buscando palabras duplicadas consecutivas como los ejemplos.

-- a wrapper that allows you to give the input as a String
repititions :: String -> [String]
repititions s = repititionsLogic (words s)
-- dose the real work 
repititionsLogic :: [String] -> [String]
repititionsLogic [] = []
repititionsLogic [a] = []
repititionsLogic (a:as) 
    | ((==) a (head as)) = a : repititionsLogic as
    | otherwise = repititionsLogic as

Sobre la base de lo que respondió Alexander Prokofyev:

repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (word (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))

Eliminar paréntesis innecesarios:

repetitions x = concat (map tail (filter (\x -> length x > 1) (List.group (word (filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x)))))

Use $ para eliminar más paréntesis (cada $ puede reemplazar un paréntesis de apertura si el paréntesis final está al final de la expresión):

repetitions x = concat $ map tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x

Reemplace los rangos de caracteres con funciones de Data.Char, combine concat y map:

repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

Usa una sección y curry en estilo sin puntos para simplificar (\x -> length x > 1) to ((>1) . length). Esto combina length con (& Gt; 1) (un operador parcialmente aplicado, o sección ) en una tubería de derecha a izquierda.

repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

Eliminar explícita " x " variable para hacer que la expresión general no tenga puntos:

repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)

Ahora toda la función, que se lee de derecha a izquierda, es una tubería que filtra solo caracteres alfa o separadores, los divide en palabras, los divide en grupos, filtra esos grupos con más de 1 elemento y luego reduce los grupos restantes al primer elemento de cada uno.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top