Показать список слов, повторенных в haskell - PullRequest
4 голосов
/ 31 декабря 2008

Мне нужно иметь возможность написать функцию, которая показывает повторяющиеся слова из строки и возвращает список строк в порядке ее появления и игнорирует не буквы

например, при запросе объятий

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

Ответы [ 4 ]

8 голосов
/ 31 декабря 2008

Чтобы разбить строку на слова, используйте функцию words (в Prelude). Чтобы исключить несловарные символы, filter с Data.Char.isAlphaNum. Поместите список вместе с хвостом, чтобы получить соседние пары (x, y). Сверните список, составив новый список, содержащий все x, где x == y.

что-то вроде:

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

Я не уверен, что это работает, но это должно дать вам приблизительное представление.

2 голосов
/ 31 декабря 2008

Я новичок в этом языке, поэтому мое решение может показаться некрасивым в глазах ветерана Хаскелла, но в любом случае:

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

Эта часть удалит все не буквы и не пробелы из строки s :

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

Этот разделит строку s на слова и сгруппирует те же слова в списки, возвращая список списков:

List.group (words s)

Когда эта часть удалит все списки, содержащие менее двух элементов:

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

После чего мы объединяем все списки в один, удаляя из них один элемент, хотя

concat (map tail s)
0 голосов
/ 02 февраля 2009

Опираясь на то, на что Александр Прокофьев ответил:

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

Удалить лишние скобки:

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

Используйте $ для удаления дополнительных скобок (каждый $ может заменить открывающую скобку, если конечная скобка находится в конце выражения):

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

Заменить диапазоны символов функциями из Data.Char, объединить concat и map:

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

Используйте раздел и карри в стиле без очков, чтобы упростить (\x -> length x > 1) to ((>1) . length). Это объединяет length с (> 1) (частично примененный оператор или section ) в конвейере справа налево.

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

Исключить явную переменную "x", чтобы сделать общее выражение бесполезным:

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

Теперь вся функция, читающая справа налево, представляет собой конвейер, который фильтрует только буквы или символы-разделители, разбивает их на слова, разбивает на группы, фильтрует эти группы с более чем 1 элементом, а затем сокращает оставшиеся группы. к первому элементу каждого.

0 голосов
/ 13 января 2009

Это может быть не элегантно, но концептуально очень просто. Я предполагаю, что он ищет последовательные повторяющиеся слова, как в примерах.

-- 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...