这里我们需要得到给定长度的所有子序列。如何计算给定函数的渐近复杂度?
import Data.List
subsequencesOfSize l n = [x | x <- subsequences l, length x == n]
多少&#34;迭代&#34;那将会?我们可以谈论&#34;迭代&#34;。任何优化? GHC 7.10.2。编译器或程序员如何改进这个?
答案 0 :(得分:1)
我认为你的问题包含至少2个不同的问题,但是GHC的当前版本是否可以优化这个
subsequencesOfSize l n = [x | x <- subsequences l, length x == n]
类似
subsequencesOfSize l n = [x | x <- subsequences l, lengthIsGt n x, length x == n]
非常值得怀疑 - 我还不是优化,超级编译等方面的专家,但是在这里使用lengthIsGt
来推断像length
这样的东西的需要似乎非常重要并且不太可能成为编译器的一组通用优化的一部分。
P.S。实际上,如果在包含lengthIsGt
的条件(但无论如何都是伪代码)之前评估包含length
的条件,lengthIsGt
的版本仍可能会尝试评估无限列表
答案 1 :(得分:1)
这是一个相关的SO问题,讨论了subsequencesOfSize
的各种实现:
Haskell: comparison of techniques for generating combinations
是使用记忆的最佳表现:
Haskell: comparison of techniques for generating combinations
<强>更新强>
还要考虑@ user3237465在评论中提到的这个版本:
subsequencesOfSize :: Int -> [a] -> [[a]]
subsequencesOfSize n xs | n > length xs = []
subsequencesOfSize n xs = subsequencesBySize xs !! n where
subsequencesBySize [] = [[[]]]
subsequencesBySize (x:xs) = zipWith (++) ([] : map (map (x:)) next) (next ++ [[]])
where next = subsequencesBySize xs