3

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

[(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
4

4 回答 4

7

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

    | 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
  • isTheSame与 相同elem,只是其参数颠倒了

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

eliminate [] = []
eliminate (x:xs)
  | x `elem` xs = eliminate $ filter (/=x) xs
  | otherwise = x : eliminate xs      
于 2013-04-02T18:56:56.910 回答
5

这应该这样做:

-- 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 的带领下,这是一个简短的版本(尽管它会返回排序的结果):

import Data.List

unique xs = [x | [x] <- group . sort $ xs]
于 2013-04-02T18:56:45.017 回答
4

低效的参考实现。

import Data.List

dups xs = xs \\ nub xs
eliminate xs = filter (`notElem` dups xs) xs
于 2013-04-02T19:32:45.950 回答
3

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

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 _ = []
于 2013-04-02T19:06:21.063 回答