函数式编程语言中多个字符串连接(连接)的时间复杂度

Time complexity of multiple string concatenation (join) in functional programming languages

我是对的,唯一可以用 Haskell 等函数式编程语言实现的算法来连接多个字符串(即实现 join 将行列表 ["one", "two", "three"] 转换为一个"onetwothree") 行的时间复杂度为 O(n^2),如 this well-known post?

中所述

例如如果我使用不可变字符串,例如,在 Python 中,并尝试实现 join,我会得到类似

的结果
def myjoin(list_of_strings):
   return list_of_strings[0] + myjoin(list_of_strings[1:])

是不是真的不能让它更快,比如在Haskell?

首先 Haskell 是懒惰的:这意味着如果你写:

concat ["foo", "bar", "qux"]

它将不会执行此操作,直到您请求例如结果的第一个字符。在这种情况下,通常它不会将 all 字符串连接在一起,但是 - 取决于函数实现的智能程度 - 旨在完成获取第一个字符所需的最少工作量。如果您请求第一个字符,但不检查它,您可能得到 succ 'f' 而不是 'g',因为 Haskell 又是懒惰的。

但是假设我们对结果字符串感兴趣,并且想知道每个字符。我们可以将 concat 实现为:

concat :: [[a]] -> [a]
concat [] = []
concat (x:xs) = x ++ concat xs

(++)为:

(++) :: [a] -> [a] -> [a]
(++) []     ys = ys
(++) (x:xs) ys = x : (xs ++ ys)

现在这意味着 - 给定 (:)O(1) 中工作 - (++)O(a)[ 中工作=46=] 和 a 第一个列表的长度,以及 b (注意这不是在大 oh 表达式中)的长度第二个列表。

所以现在如果我们检查 concat,我们会看到如果我们输入 k 个字符串,我们将执行 k (++)操作。在每次 (++) 操作时,左边的字符串等于字符串的长度。所以这意味着如果字符串的长度总和是 nconcat 是一个 O(n)算法.