【发布时间】:2018-08-17 16:29:13
【问题描述】:
这是 Richard Bird 用 Haskell 进行函数式思考 (p. 158) 中的一个例子。有人可以解释一下 1、2、3 和 4 背后的原因吗?
编辑。 我理解从第一个定义形成的前 3 个方程。对于 1.,为什么是求和?它与 T(++)(n, m) = Θ(n) 有什么关系? 对于第二个定义,我理解前两个陈述。第三个(2.),为什么是 k+n? 对于 3. 和 4. 我完全迷路了
首先考虑以下两个concat的定义:
concat xss= foldr (++) [] xss
concat' xss = foldl (++) [] xss
如果 xss 是一个有限列表,这两个定义是等价的。假设 xss 是长度为 m 的列表,其中列表的长度均为 n。那么第一个定义给出了
T(concat)(m, n) = T(foldr (++) [])(m, n),
T(foldr (++) [])(0, n) = Θ(1),
T(foldr (++) [])(m+1, n) = T(++)(n, mn) + T(foldr (++) [])(m, n).
估计 T(++)(n, mn) 的出现是因为长度为 n 的列表与长度为 mn 的列表连接在一起。由于 T(++)(n, m) = Θ(n),我们得到
1. T(foldr (++) [])(m,n) = Σ_{k=0}^{m} Θ(n) = Θ(mn)
对于 concat 的第二个定义,我们有
T(concat')(m, n) = T(foldl (++))(0, m, n),
T(foldl (++))(k, 0, n) = O(1),
2. T(foldl (++))(k, m+1, n) = T(++)(k, n) + T(foldl (++))(k+n, m, n).
附加参数 k 指的是 foldl 的第二个参数中累积列表的长度。这次我们获得了
3. T(foldl (++)) (k,m,n) = Σ_{j=0}{m-1} Θ(k+jn) = Θ(k+m^2n)
因此
4. T(concat')(m, n) = Θ(m_2 n)
【问题讨论】:
-
我认为您应该详细说明您不清楚的地方。在我看来,您发布的内容已经解释了 1..4 背后的原因。如果您想要/需要更多信息,提供更多信息会有所帮助。例如。 “在 X 之前我什么都明白。接下来的步骤要求 Y——为什么 Y 应该持有?”
-
我编辑了我的原始帖子。
-
不那么冗长的符号可能会有所帮助。例如,对于 #1,f(m+1, n) = n + f(m, n)。等价: f(m) = n + f(m − 1) 其中 n 不变。你能看到你是如何将 f 重写为求和的吗?
标签: haskell functional-programming time-complexity