Удалите повторяющиеся элементы списка, используя рекурсию и сопоставление с образцом в Haskell - PullRequest
0 голосов
/ 11 мая 2018

Я делаю функцию, которая удаляет элементы, которые встречаются два или более раз подряд в списке.Он заменяет их одним случаем.Я использую только рекурсию и сопоставление с образцом (без функций списка библиотек).

Примеры работы функции:

  • unrepeat [True,True,True,True] -> [True]
  • unrepeat [1,1,2,1,3,3,3] -> [1,2,1,3]

Что у меня есть до сих пор:

unrepeat :: Eq a => [a] -> [a]
unrepeat [] = []
unrepeat [x] = [x]
unrepeat (x:xs) = x : [ k | k <- unrepeat(xs), k /=x]

Ответы [ 2 ]

0 голосов
/ 12 мая 2018

Ну, у меня есть три, одна стандартная рекурсия, одна foldr рекурсия и одно понимание списка. Каждый делает то же самое и с любым списком, включая Boolean.

Сначала стандартная рекурсия

rd [] = []; rd (x:xs) = x: rd (filter (/=x) xs)

Это довольно эффективно. Сокращает список до последней главы списка, отфильтровывая совпадения.

Сокращение поддается складкам.

rd2 ls = foldr (\x acc -> x:filter (/=x) acc) [] ls

Этот foldr делает то же самое, что и rd до него. Это более кратко, потому что условие остановки неявно, конец списка.

Понимание списка также неявно прекращается.

rd3 ls = [d|(z,d)<- zip [0..] ls,notElem d $ take z ls]

Удаление дубликатов в составных списках - это функция union. Все это работает без импорта.

0 голосов
/ 11 мая 2018

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

Дайте попробовать:

unrepeat :: Eq a => [a] -> [a]
unrepeat [] = []
unrepeat [x] = [x]
unrepeat (x1:x2:xs) = if x1 == x2 then unrepeat(x2:xs) else x1:unrepeat(x2:xs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...