如何解决str.replace() 是否有 O(n^2) 的时间复杂度?
我试图找出 Python 内置的 str.replace()
的时间复杂度,这是我设法收集的数据(此处和其他站点):
我知道 replace()
是基于 Boyer–Moore 算法的,该算法需要 O(n*m) 的最坏情况时间来查找子字符串,但这是针对 单个子串?
当 replace()
找到第一个子字符串然后再次开始搜索时,它是否返回“固定”字符串的副本?
当我们多次出现一个子字符串时会怎样,如下例所示:
old_string = '192.168.1.1'
new_string = old_string.replace('.','|')
如果一次只能替换一个子串,那么对于单个子串,我们得到 O(n*m) 乘以最大 n/m 的子串数。这就是 O(n^2)!
假设一个简单的循环需要 O(n),例如:
old_string = '192.168.1.1'
new_string = []
for ch in old_string:
new_string.append('|' if ch == '.' else ch)
有意义吗?我错过了什么吗?
内置的 replace() 是否会因多次替换而存在缺陷,或者它的实现方式是否可以从中断的地方继续?
解决方法
最坏的情况是O(n*(m1 + m2/m1))
,其中n
是字符串的长度,m1
是搜索到的字符串的长度,m2
是替换的长度.
平均情况是 O(n * (1 + m2/m1))
。
原则上算法如下所示:
initialize data structures. # max time O(n)
while find next match: # max time O(n*m1)
copy unchanged string. # max time O(n)
copy replacement # max time O((n/m1) * m2) + O(n)
copy rest of the string # max time O(n)
有很多细节。 (例如,他们必须管理内存,并在替换是原始大小的情况下采用快速路径。)但这里解释了每个步骤以及为什么需要花费这些时间。
- 您正在初始化数据结构以获取结果。这个初始化速度很快,但是初始化是
O(n)
数据所以时间O(n)
。 - 查找所有匹配项是最糟糕的情况,即对于您向前比较
m1-1
个字符的每个字符,匹配最后一个失败,请备份并重试。因此,这可以是O(n*m1)
。 - 复制
O(n)
数据需要O(n)
时间。 - 最多可以有
O(n/m1)
个匹配项,我们为每个匹配项复制m2
个数据。然而,我们也可以超过我们分配的用于放置数据的大小。在这种情况下,我们必须创建一个新位置来放置数据,复制我们所做的,然后继续。选择调整大小的阈值以使总成本具有最大O(n)
时间成本。 - 最后一场比赛后最多可以有
O(n)
条数据。
将这些相加并将 O(n)
项吸收到 O(n*m1)
中,您就可以得到原始估计值。
回到一般情况,字符串搜索通常不会在回退之前接近子字符串的末尾。大多数字母不匹配。大多数情况下,如果第一个字母匹配,则第二个不匹配。等等。所以搜索通常是O(n)
。去掉它,你就会得到另一个估计。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。