如何使用列表删除函数中的重复元素?
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)
操作。您可以使用map
、group
和head
函数来完成此操作。
有了这些建议,下面是编写函数的另一种方式:
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 中的列表从列表中删除重复元素?
如何使用 lambda 删除列表列表中数字下方的元素? Python [重复]