从列表中删除重复项

发布于 2024-10-05 23:56:24 字数 1397 浏览 6 评论 0原文

我有数据类型:

data SidesType = Sides Int Int Int deriving (Show)

我需要一个函数来获取 SidesType 列表并从中删除重复项。

*Main> let a = [Sides 3 4 5,Sides 3 4 5,Sides 5 12 13,Sides 6 8 10,Sides 6 8 10,Sides 8 15 17,Sides 9 12 15,Sides 5 12 13,Sides 9 12 15,Sides 12 16 20,Sides 8 15 17,Sides 15 20 25,Sides 12 16 20,Sides 15 20 25]
*Main> removeDuplicateFromList [] a
[Sides 3 4 5,Sides 5 12 13,Sides 6 8 10,Sides 6 8 10,Sides 8 15 17,Sides 9 12 15,Sides 5 12 13,Sides 9 12 15,Sides 12 16 20,Sides 8 15 17,Sides 15 20 25,Sides 12 16 20,Sides 15 20 25]

这是我的解决方案:

removeElementFromList :: [SidesType] -> SidesType -> [SidesType]
removeElementFromList lst element  = 
                      let (Sides a b c) = element
                      in [(Sides x y z) | (Sides x y z) <- lst, (x /= a) || (y /= b)]

removeDuplicateFromList :: [SidesType] -> [SidesType] -> [SidesType]
removeDuplicateFromList inlist outlist 
                        | (length outlist) == 0 = inlist
                        | otherwise = 
                          let element = head outlist
                              b = tail outlist
                              filtered = removeElementFromList b element
                      in removeDuplicateFromList (inlist ++ [element]) filtered

我只是想知道是否还有其他方法可以以更多 haskell 方式编写此代码?

I have datatype:

data SidesType = Sides Int Int Int deriving (Show)

And I need a function which get a list of SidesType and remove duplicates from it.

*Main> let a = [Sides 3 4 5,Sides 3 4 5,Sides 5 12 13,Sides 6 8 10,Sides 6 8 10,Sides 8 15 17,Sides 9 12 15,Sides 5 12 13,Sides 9 12 15,Sides 12 16 20,Sides 8 15 17,Sides 15 20 25,Sides 12 16 20,Sides 15 20 25]
*Main> removeDuplicateFromList [] a
[Sides 3 4 5,Sides 5 12 13,Sides 6 8 10,Sides 6 8 10,Sides 8 15 17,Sides 9 12 15,Sides 5 12 13,Sides 9 12 15,Sides 12 16 20,Sides 8 15 17,Sides 15 20 25,Sides 12 16 20,Sides 15 20 25]

Here is my solution:

removeElementFromList :: [SidesType] -> SidesType -> [SidesType]
removeElementFromList lst element  = 
                      let (Sides a b c) = element
                      in [(Sides x y z) | (Sides x y z) <- lst, (x /= a) || (y /= b)]

removeDuplicateFromList :: [SidesType] -> [SidesType] -> [SidesType]
removeDuplicateFromList inlist outlist 
                        | (length outlist) == 0 = inlist
                        | otherwise = 
                          let element = head outlist
                              b = tail outlist
                              filtered = removeElementFromList b element
                      in removeDuplicateFromList (inlist ++ [element]) filtered

I am just wondering if there is any other way to write this code in more haskell-way ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半山落雨半山空 2024-10-12 23:56:24

像往常一样,有“By”函数增加了灵活性:

nubBy :: (a -> a -> Bool) -> [a] -> [a]

PS虽然它是 O(n^2)

As usual there is "By" function which adds flexibility:

nubBy :: (a -> a -> Bool) -> [a] -> [a]

PS Although it's O(n^2)

不甘平庸 2024-10-12 23:56:24

您已经为您的数据类型派生了 Show。如果您还派生 Eq,则可以使用 模块 Data.List 中的 nub

You're already deriving Show for your datatype. If you also derive Eq, you can use nub from module Data.List.

小耗子 2024-10-12 23:56:24

使用 Data.List.nub

Use Data.List.nub

少女情怀诗 2024-10-12 23:56:24

首先还派生订单类:

data XYZ = XYZ .... deriving (Show, Eq, Ord)

或者在 Eq 实例上编写您的:

instance Eq XYZ where
a == b = ...

然后聪明地使用树! [计算机科学树从上到下生长!][1]

import qualified Data.Map.Strict as Map

removeDuplicates ::[a] -> [a]
removeDuplicates list = map fst $ Map.toList $ Map.fromList $ map (\a -> (a,a)) list

长度为 N 的列表的复杂度(从右到左):

  1. 列表的映射: O(N)
  2. Map.fromList: O(N*log N)
  3. Map.toList : O(log N)
  4. 映射列表长度小于或等于 N 的列表: O(N)

它们被连续调用,这意味着,各部分的复杂性之间存在优势 => O(2 * N + N * log N + log N) = O(N * log N)

这比遍历列表 N^2 次要好得多!
请参阅:wolframAlpha 图。出于比较的原因,我也包括了 2*N。

2+3: http://hackage.haskell .org/package/containers-0.5.4.0/docs/Data-Map-Strict.html

[1]:在维基百科中搜索计算机科学树

First derive the order class also:

data XYZ = XYZ .... deriving (Show, Eq, Ord)

Or write your on Eq instance:

instance Eq XYZ where
a == b = ...

Then be intelligent and use a Tree! [Computer Science Trees grow from top to bottom!][1]

import qualified Data.Map.Strict as Map

removeDuplicates ::[a] -> [a]
removeDuplicates list = map fst $ Map.toList $ Map.fromList $ map (\a -> (a,a)) list

Complexity (from right to left) for list with length N:

  1. map of the list: O(N)
  2. Map.fromList: O(N*log N)
  3. Map.toList: O(log N)
  4. map over list with list length smaller or equal to N: O(N)

They are called consecutively, this means, there are pluses between the complexities of the parts => O(2 * N + N * log N + log N) = O(N * log N)

This is way better than traversing N^2 times over the list!
See: wolframAlpha plots. I included 2*N also for comparison reasons.

2+3: http://hackage.haskell.org/package/containers-0.5.4.0/docs/Data-Map-Strict.html

[1]: Search wikipedia for Computer Science Tree

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文