函数式编程语言中多个字符串连接(连接)的时间复杂度
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 (++)
操作。在每次 (++)
操作时,左边的字符串等于字符串的长度。所以这意味着如果字符串的长度总和是 n,concat
是一个 O(n)算法.
我是对的,唯一可以用 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 (++)
操作。在每次 (++)
操作时,左边的字符串等于字符串的长度。所以这意味着如果字符串的长度总和是 n,concat
是一个 O(n)算法.