python字符串匹配时间复杂度

时间:2013-03-27 18:24:48

标签: python string time match complexity-theory

我需要这个问题的帮助。我认为时间复杂度是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") 

这是我的算法:

  1. s在subStr中:
    • 循环开始于:“string_expression_matcher.cc”
    • 此步骤的剩余字符串输出为:“tring_expression_matcher.cc”
  2. t in subStr
    • 循环开始于:“tring_expression_matcher.cc”
    • 剩下的是:“ring_expression_matcher.cc”
  3. x in subStr
    • 循环开始于:“ring_expression_matcher.cc”
    • 剩下的是:“pression_matcher.cc”
  4. p in subStr
    • 循环开始于:“pression_matcher.cc”
    • 剩下的是:“ression_matcher.cc”
  5. 等等到最后一步。

    假设:

    n = len(subStr)
    m = len(string)`
    

    这个计划的时间复杂度是多少? 谢谢大家,但我真的想知道O(n)还是O(n ^ 2)。我知道代码并不完美但请关注时间复杂度.. 非常感谢

    有谁知道python字符串副本是如何工作的?当我们做fn = fn [index + 1 ::]?

    时会发生什么

    我问了一位杰出的工程师。他说结果是O(m * n)。你呢?

3 个答案:

答案 0 :(得分:1)

您的算法(根据比较次数)为O(n),其中n是字符串的长度。在最坏的情况下,字符串和模式都是相同的,然后对于subStr中的每个字符,您将移动到string的下一个字符。这相当于简单的字符串比较。

但是,就其他操作而言,您的实施可能是O(n^2),正如您在问题中提到的那样,其原因如下:

fn = fn[index+1 ::]

这有效地复制了字符串(假设上面的片段是作为副本实现的)。如果再次考虑前面的示例,对于字符串中的每个字符,您必须复制所有剩余字符,即O(n^2)。这是因为您将首先复制n-1个字符,然后复制n-2n-3等等,在最后一次迭代中,您只复制一个字符。然后,要复制的项目总金额为n-1 + n-2 + ... + 1arithmetic 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)。为什么呢?

  1. 迭代具有O(n)复杂度的源字符串
  2. 在每次迭代中,您在字符串上调用“index”,该字符串也具有O(n)复杂度
  3. 因此,这是由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