什么是最有效的纯函数算法来生成列表的所有前缀?

prefixes ls = zipWith take [1 .. length ls] (repeat ls)

有什么办法做得比这更好吗?直观地,在我看来,在纯功能语言中,无法获得低于O(n²)的算法,因为反向或追加必须被应用n次.我不知道如何证明这一点.

最佳答案
我想你是对的.由于所有的尾巴都不同,所以不能共享列表的脊柱.因此,如果完全评估,前缀列表将采用完整的Θ(n2)空间,必须采用Ω(n2)时间才能生成.

请注意,您写的函数(的更简单版本)可以在Data.List中作为inits.

你可以做一个整洁的优化.这个方程式成立:

map (foldl f z) . inits = scanl f z

并且scanl以线性时间运行.因此,如果您可以将每个前缀要做的事情作为左折叠进行短语,那么可以避免构建前缀列表的二次方复杂性.

转载注明原文:什么是最有效的纯函数算法来生成列表的所有前缀? - 代码日志