удаление дубликатов из списка в haskell - PullRequest
0 голосов
/ 22 декабря 2019

Я пытаюсь удалить последовательные дубликаты в списке;например, учитывая список [1,2,2,3,4], если нужная мне функция должна возвращать [1,3,4].

Мой код в конце вопроса, однако, не работает, если в списке есть конечные дубликаты, напримерв [1,2,3,4,4].

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

myCom :: Eq a => [a] -> [a]
myCom (x:y:ys@(z:_))
    | x == y    =  myCom ys
    | otherwise = x  : myCom (y:ys)
myCom ys = ys

Ответы [ 3 ]

4 голосов
/ 22 декабря 2019

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

myCom [4,4] 

, он просто использует

myCom ys = ys

и возвращает себя. Вы можете поймать это, определив myCom для списков, по крайней мере, с 2 элементами, как показано ниже (вы все равно не использовали z):

myCom (x:y:ys)
  | x == y    =  myCom ys
  | otherwise = x  : myCom (y:ys)
myCom ys = ys

Это дает

myCom [1,2,2, 3,4,4] = [1,3]

По-прежнему существует проблема с 3 (нечетным числом) последовательных чисел. Например, мы получаем:

myCom [1,2,2,2] = [1,2]

, но я понимаю, что это желаемое поведение.

1 голос
/ 24 декабря 2019

Я бы использовал Maybe для представления длины единицы в качестве условия успеха. Это хорошо работает с синтаксисом соответствия шаблонов в Haskell. Затем вы можете использовать group (из Data.List) и отфильтровать Nothing s, используя catMaybe (из Data.Maybe):

myCom = catMaybes . map lenOne . group
  where lenOne [x] = Just x
        lenOne _   = Nothing
1 голос
/ 22 декабря 2019

Из комментария я вижу, что функция Data.Set.nub просто выполняет то, что запрашивает OP.

Однако моей первой попыткой решить проблему была следующая, которая удаляет дубликаты, только если они являются последовательными (например,[1,2,1,2,1,2] не изменяется):

concat $ filter (\x -> length x == 1) $ Data.List.group [1,2,3,4,4]

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

...