【问题标题】:removing duplicates from a list in haskell从haskell中的列表中删除重复项
【发布时间】:2019-12-26 16:18:55
【问题描述】:

我正在尝试删除列表中的连续重复项;例如,给定列表[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

【问题讨论】:

  • 你是指所有重复的,还是只是连续的?
  • nub 不幸的是 O(n^2) - 我认为最好的方法是使用 Data.Set 中的 fromListtoList 函数,然后使用 toList . fromList
  • @tex 否,nub [1,2,2,3,4][1,2,3,4],但 OP 想要 [1,3,4]
  • 好电话。我误解了要求。

标签: list haskell duplicates


【解决方案1】:

您拥有的第一个模式匹配仅捕获具有至少 3 个元素的列表。 这就是为什么当重复项在列表末尾时

myCom [4,4] 

被称为它只是使用

myCom ys = ys

并返回自身。您可以通过为具有至少 2 个元素的列表定义 myCom 来捕获这一点(无论如何您都没有使用 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]

但我知道这是期望的行为。

【讨论】:

  • 我认为这是正确的答案,您只需要调整第一个模式匹配即可。
  • 如果myCom [1,2,2,2] = [1,2] 是期望的行为,那么myCom [1,2,2,2,2] 应该是什么?又是[1],还是[1,2,2]
【解决方案2】:

我会使用Maybe 表示长度为 1 作为成功条件。这适用于 Haskell 的模式匹配语法。然后您可以使用group(来自Data.List)并使用catMaybe(来自Data.Maybe)过滤掉Nothings:

myCom = catMaybes . map lenOne . group
  where lenOne [x] = Just x
        lenOne _   = Nothing

【讨论】:

    【解决方案3】:

    从评论中我看到函数 Data.Set.nub 只是执行 OP 的要求。

    但是,我第一次尝试解决这个问题是这样的,它只删除连续的重复项(例如,[1,2,1,2,1,2] 没有更改):

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

    我希望这个答案对最终访问此页面的一些随机用户有用。

    【讨论】:

    • 虽然这很容易阅读,但它可能效率低下,因为lengthtraverses the whole list,只是为了检查没有第二个元素。
    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 2013-04-13
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 2014-09-30
    • 2021-04-02
    • 2016-01-28
    相关资源
    最近更新 更多