我需要这个问题的帮助。我认为时间复杂度是O(n),但我的朋友坚持认为这是O(n ^ 2)。其中一个原因是因为fn = fn[index+1 ::]
#filename: string_expression_matcher.cc
#string: stxpm.c
#should return
import sys
string = "string_expression_matcher.cc"
subStr = "stxpm.c"
fn = list(string)
for i in subStr:
try:
index = fn.index(i)
fn = fn[index+1 ::]
except:
print ("can't dup")
sys.exit()
print ("found")
这是我的算法:
等等到最后一步。
假设:
n = len(subStr)
m = len(string)`
这个计划的时间复杂度是多少? 谢谢大家,但我真的想知道O(n)还是O(n ^ 2)。我知道代码并不完美但请关注时间复杂度.. 非常感谢
有谁知道python字符串副本是如何工作的?当我们做fn = fn [index + 1 ::]?
时会发生什么我问了一位杰出的工程师。他说结果是O(m * n)。你呢?
答案 0 :(得分:1)
您的算法(根据比较次数)为O(n)
,其中n
是字符串的长度。在最坏的情况下,字符串和模式都是相同的,然后对于subStr
中的每个字符,您将移动到string
的下一个字符。这相当于简单的字符串比较。
但是,就其他操作而言,您的实施可能是O(n^2)
,正如您在问题中提到的那样,其原因如下:
fn = fn[index+1 ::]
这有效地复制了字符串(假设上面的片段是作为副本实现的)。如果再次考虑前面的示例,对于字符串中的每个字符,您必须复制所有剩余字符,即O(n^2)
。这是因为您将首先复制n-1
个字符,然后复制n-2
,n-3
等等,在最后一次迭代中,您只复制一个字符。然后,要复制的项目总金额为n-1
+ n-2
+ ...
+ 1
,arithmetic progression等于{{1} }}。对于其他情况,这可以推广到(n-1)*((n-1)+1)/2 = (n-1)*n/2 = O(n^2)
,其中O(m*n)
是模式的长度。
您的朋友可能想告诉您的是:您的算法是线性的,但您的实现不是。它可以轻松解决。使用@thkang提供的解决方案或更透明的解决方案来消除隐藏的复杂性,例如:
m
答案 1 :(得分:1)
很抱歉,但这既不是O(n)也不是O(n + m)。它们都比O(n ^ 2)好,并且该算法是O(n ^ 2)。为什么呢?
因此,这是由O(n ^ 2)限制的最坏情况性能,并且实际上是朴素搜索算法的实现。如果你想看O(n)/ O(mn),我建议你查看Boyer-Moore algorithm
答案 2 :(得分:0)
如果您不想复制整个列表,请使用.index
并指定起始索引。
last_index = 0
for i in subStr:
try:
last_index = fn.index(i, last_index) + 1
except ValueError:
print ("can't dup")
sys.exit()
else:
#string matches