jfo*_*erg 7 algorithm performance haskell
我对Haskell标准库Data.List中 'nub'(选择唯一值)函数的实现感到困惑.GHC的实施是
nub l = nub' l []
where
nub' [] _ = []
nub' (x:xs) ls
| x `elem` ls = nub' xs ls
| otherwise = x : nub' xs (x:ls)
Run Code Online (Sandbox Code Playgroud)
据我所知,这有一个最坏情况下的时间复杂度为O(n ^ 2),因为对于一个唯一值列表,它必须比较它们一次才能看到它们实际上是唯一的.
如果使用哈希表,则复杂性可以减少到O(n)以构建表+ O(1)以检查每个值与哈希表中的先前值.当然,这不会产生有序列表,但如果有必要,也可以在O(n log n)中使用GHC自己的有序Data.Map.
为什么为重要的库函数选择这种低效的实现?我知道效率不是Haskell的主要关注点,但至少标准库可以努力为工作选择(渐近)最佳数据结构.
Eri*_*ikR 10
你绝对正确 - nub
是一个O(n ^ 2)算法.但是,仍然有理由要使用它而不是使用hashmap:
nub
只需要Eq
约束; 相比之下,Data.Map
需要Ord
对键进行约束,并且Data.HashMap
需要具有both Hashable
和Ord
type类的键类型编辑:对第三点进行轻微修正 - 您无需处理整个列表即可开始获取结果; 你仍然需要检查输入列表的每个元素(因此nub
不能在无限列表上工作),但是一旦找到一个唯一的元素,你就会开始返回结果.
在Haskell中,效率是一个非常值得关注的问题,毕竟语言与Java相当,并且在内存消耗方面胜过它,但当然不是C语言.
你的问题的答案很简单:Prelude nub
只需要一个Eq
约束,而任何实现基于Map
或者Set
也需要一个Ord
或Hashable
.
归档时间: |
|
查看次数: |
1572 次 |
最近记录: |