繁体   English   中英

哈斯克尔的“尾巴”函数有什么时间复杂性?

[英]What Time Complexity Does Haskell's “tail”-Function Have?

当我想到自己时,我正在阅读关于Haskell的教程; Haskell的tail函数具有什么时间复杂度(以及为什么)? (我在任何文档中都找不到答案)

我猜想对于大小为n的列表, tail函数将是O(n) ,即只是将尾部复制到新列表并返回该列表。 但话说回来,我不太了解Haskell的底层架构(我是语言的新手)。

当然,我可以计时。 但我还不知道如何在Haskell中计算时间,我也想了解Haskell如何处理问题,证明为什么它是O(n)/ O(1)或其他什么。

提前致谢 :)

Haskell语言没有指定。 但在GHC(最常用的实现)中,它是O(1)。 尾部不需要复制 - 在原始列表和只使用列表尾部的人之间共享是安全的 - 因为Haskell中的所有内容都是不可变的。

挑战问题:为什么除了列表的最后一个元素之外的所有init都在O(n)中运行? 为什么上面的共享参数不适用于那里?

简短回答:如果列表已构建到该节点,则为O(1)

Haskell中的列表是一个链表 它被定义为:

data [a] = [] | a : [a]

这意味着要么我们有空列表,要么是a : [a]构造。 因此,具有heada )的节点引用类型a的对象, tail引用列表[a] (可以是空列表或另一个节点)。

base tail的源代码定义为:

 tail :: [a] -> [a] tail (_:xs) = xs tail [] = errorEmptyList "tail" 

它在O(1)中运行,因为我们只需按指向该节点的“尾部”。

但请注意Haskell懒惰地工作 这不是因为我们得到一个类型为[a]的对象,我们有一个物化列表:通常Haskell首先必须评估它已经放弃给定节点的表达式树 这可能导致评估复杂且耗时的算法。 所以它取决于你给出的表达式树

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM