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

时间:2017-09-07 10:00:31

标签: functional-programming time-complexity string-concatenation

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

中所述

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

的内容
def myjoin(list_of_strings):
   return list_of_strings[0] + myjoin(list_of_strings[1:])

是不是可以让它更快,例如,在Haskell中?

1 个答案:

答案 0 :(得分:2)

首先,Haskell懒洋洋地说:这意味着如果你写:

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

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

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

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

(++) as:

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

现在这意味着 - 给定(:) O(1)中工作 - (++) O(a)中使用 a 第一个列表的长度, b (请注意,这不是大哦表达式)第二个列表的长度。

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