如何使用列表删除函数中的重复元素?

Posted

技术标签:

【中文标题】如何使用列表删除函数中的重复元素?【英文标题】:How to remove a duplicated element in a function with a list? 【发布时间】:2018-02-27 11:28:19 【问题描述】:

当谈到 Haskell 时,我是一个新手,我对一些事情感到困惑。我正在尝试删除此函数列表中的重复元素:

qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = 
     qsort smaller ++ [x] ++ qsort larger
     where 
          smaller = [a | a <- xs, a <= x] 
          larger = [b | b <- xs, b > x]

我尝试通过导入 Data.List 并使用 nub [] 函数来做到这一点:

qsort :: [Int] -> [Int]
qsort [] = nub[]

但是,如果我执行 qsort [2, 6, 3, 3],它仍然返回 [2, 3, 3, 6]。

是我使用了 nub 函数错误还是我遗漏了什么?

谢谢

【问题讨论】:

你为什么在qsort [] = nub []中写[] 【参考方案1】:

您的示例显示您仅在空列表 (nub []) 上使用 nub,这实际上并没有做任何事情。你必须将它应用到qsort的主体结果中:

qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) = 
     nub $ qsort smaller ++ [x] ++ qsort larger
     where 
          smaller = [a | a <- xs, a <= x] 
          larger = [b | b <- xs, b > x]

然而,这非常昂贵,因为它在函数的每个分支上运行nub。进一步的优化留给您。

【讨论】:

【参考方案2】:

正如@Chad Gilbert's 答案中所指出的,您需要在最终排序列表上应用nub。不幸的是,这个函数是O(n^2),如果列表很长,效率会很低。

如果您将相同的元素组合在一起并只取第一项,那么您可以将整体复杂性提高到O(nlogn)(排序成本),这只是一个O(n) 操作。您可以使用mapgrouphead 函数来完成此操作。

有了这些建议,下面是编写函数的另一种方式:

import Data.List

qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (pivot:others) = map head $ group $ qsort lowers ++ [pivot] ++ qsort highers
    where lowers = filter (<pivot) others
          highers = filter (>=pivot) others

其工作原理如下:

*Main> qsort [2, 6, 3, 3]
[2,3,6]

【讨论】:

【参考方案3】:

查看(唯一)[https://hackage.haskell.org/package/Unique-0.4.7.2/docs/Data-List-Unique.html] 包中的unique 函数。

unique [2,3,6,6,3]
[2,3,6]

【讨论】:

以上是关于如何使用列表删除函数中的重复元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Dart / Flutter 中的列表从列表中删除重复元素?

python如何有多个重复元素删除其中一个?

如何从字典中的列表中删除元素[重复]

如何使用 lambda 删除列表列表中数字下方的元素? Python [重复]

如何使用原始元素删除 ArrayList 中的重复值[重复]

python如何删除list里重复的元素?