【问题标题】:Eliminating the duplicates completely in Haskell在 Haskell 中完全消除重复项
【发布时间】:2013-04-02 18:43:23
【问题描述】:

我有这段代码,但它并不能完全满足我的要求,我需要一个元组列表;

[(3,2),(1,2),(1,3),(1,2),(4,3),(3,2),(1,2)]

并给予

[(1,3),(4,3),(3,2),(1,2)]

但我希望它给予

[(1,3),(4,3)]

我哪里做错了?提前致谢。

eliminate :: [(Int,Int)] -> [(Int,Int)]
eliminate [] = []
eliminate (x:xs)
    | isTheSame xs x  = eliminate xs
    | otherwise       = x : eliminate xs


isTheSame :: [(Int,Int)] -> (Int,Int) -> Bool
isTheSame [] _ = False
isTheSame (x:xs) a
    | (fst x) == (fst a) && (snd x) == (snd a)  = True
    | otherwise                 = isTheSame xs a

【问题讨论】:

  • “完全”是什么意思,为什么要排除 (3,2)(1,2)
  • 我正在寻找一个完全消除重复的函数,只有唯一的应该在那里,我想我应该改变我的实现:/

标签: list haskell


【解决方案1】:

代码几乎正确。只需更改此行

    | isTheSame xs x  = eliminate xs

    | isTheSame xs x  = eliminate $ filter (/=x) xs   

原因是如果x 包含在xs 中,您想删除所有出现的x

也就是说,您的代码示例中有几个部分可以更优雅地表达:

  • (fst x) == (fst a) && (snd x) == (snd a)x == a 相同
  • isTheSameelem 相同,只是其参数颠倒了

因此,我们可以这样表达函数eliminate

eliminate [] = []
eliminate (x:xs)
  | x `elem` xs = eliminate $ filter (/=x) xs
  | otherwise = x : eliminate xs      

【讨论】:

  • 哇是的!我正在过滤该部分以从 xs 部分中排除 x 但我无法管理它谢谢:)
  • @Karavana:检查我的编辑,你应该使用 elem 而不是你自定义的、高度专业化的 isTheSame 函数(也有一个奇怪的名字)
  • 我正要建议改变。
  • This one,你刚刚错过了宽限期;)
  • 当我添加过滤器部分时,它给出了“消除所需的 Eq [(Int,Int)] 实例”错误,这可能是什么原因?
【解决方案2】:

应该这样做:

-- all possibilities of picking one elt from a domain
pick :: [a] -> [([a], a)]
pick []     = [] 
pick (x:xs) = (xs,x) : [ (x:dom,y) | (dom,y) <- pick xs]

unique xs = [x | (xs,x) <- pick xs, not (elem x xs)]

测试:

*Main Data.List> unique [(3,2),(1,2),(1,3),(1,2),(4,3),(3,2),(1,2)]
[(1,3),(4,3)]

更多hereSplitting list into a list of possible tuples


Landei's lead 之后,这是一个 版本(虽然它会返回排序后的结果):

import Data.List

unique xs = [x | [x] <- group . sort $ xs]

【讨论】:

  • 良好的实施 威尔,我感谢你的努力,但我对我的实施有什么问题很感兴趣,但你的很完美 :)
【解决方案3】:

低效的参考实现。

import Data.List

dups xs = xs \\ nub xs
eliminate xs = filter (`notElem` dups xs) xs

【讨论】:

    【解决方案4】:

    一个较短的版本(但结果将被排序):

    import Data.List
    
    eliminate :: [(Int,Int)] -> [(Int,Int)]
    eliminate = concat . filter ((== 1) . length) . group . sort
    

    或者Maybe(谢谢你,Marimuthu):

    import Data.List
    import Data.Maybe
    
    eliminate = mapMaybe f . group . sort where f [x] = Just x; f _ = Nothing
    

    考虑...我们可以使用列表代替Maybe

    import Data.List
    
    eliminate = (>>= f) . group . sort where  f [x] = [x]; f _ = []
    

    【讨论】:

    • 有理由使用join而不是concat吗?通过使用 concat,不需要导入 Control.Monad。
    • 没有。谢谢,我修好了。
    • eliminate = mapMaybe f . group . sort where f [x] = Just x; f _ = Nothing 因为catMaybes . map f 只是mapMaybe f
    • [x | [x] &lt;- group . sort $ xs]。 :)
    • 感谢 BTW 的灵感(对于较短的变体)。我已将其添加到我的答案中。 :)
    猜你喜欢
    • 2017-09-16
    • 1970-01-01
    • 2020-11-09
    • 2014-03-10
    • 1970-01-01
    • 2021-06-01
    • 2023-01-17
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多