Pergunta

Eu preciso ser capaz de escrever uma função que mostra repetiu as palavras de uma string e retornar uma lista de strings em ordem de sua ocorrência e ignorar os não-letras

por exemplo em abraços rápida

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"]
Foi útil?

Solução

Para dividir uma string em palavras, usar a função words (no Prelude). Para eliminar caracteres não-palavra, filter com Data.Char.isAlphaNum. Zip da lista, juntamente com sua cauda para obter pares adjacentes (x, y). Dobre a lista, consing uma nova lista que contém todos x onde x == y.

Someting como:

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

Eu não tenho certeza que as obras, mas deve dar uma idéia aproximada.

Outras dicas

Eu sou novo a esta linguagem de modo a minha solução poderia ser um tipo de feio nos olhos de um veterano Haskell, mas de qualquer maneira:

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 irá remover todas as letras não e não espaços de uma string s :

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

Este irá dividir uma string s para palavras e grupo as mesmas palavras para listas lista de listas de retorno:

List.group (words s)

Quando esta parte irá remover todas as listas com menos de dois elementos:

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

Depois do que vamos concatenar todas as listas para uma remoção de um elemento com eles embora

concat (map tail s)

Isso pode ser inelegent, no entanto, é conceitualmente muito simples. Estou assumindo que a sua procura de palavras duplicadas consecutivas como exemplos.

-- 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

Com base no que Alexander Prokofyev respondeu:

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)))))

Remova parênteses desnecessários:

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 remover mais parêntese (cada $ pode substituir um parêntese de abertura se o parêntese final é no final da expressão):

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

Substituir intervalos de caracteres com funções de Data.Char, concat merge e mapa de:

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

Use uma seção e currying em grande estilo pontos-livres para (\x -> length x > 1) to ((>1) . length) simplificar. Isto combina com length (> 1) (um operador parcialmente aplicada, ou secção ) numa tubagem da direita para a esquerda.

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

Elimine explícita variável "x" para fazer pontos-livres expressão geral:

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

Agora, toda a função, a leitura da direita para a esquerda, é um gasoduto que filtra apenas alfa ou um separador de caracteres, divide-lo em palavras, quebra-lo em grupos, filtra esses grupos com mais de 1 elemento, e depois reduz os restantes grupos para o primeiro elemento de cada um.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top