为啥看和说序列的这两种实现有不同的执行时间?

Posted

技术标签:

【中文标题】为啥看和说序列的这两种实现有不同的执行时间?【英文标题】:Why these two implementations for the look and say sequence have different times of execution?为什么看和说序列的这两种实现有不同的执行时间? 【发布时间】:2020-05-11 05:25:01 【问题描述】:

我不明白生成 look and say sequence 的这两个实现如何具有不同的执行时间,因为它们执行非常相似的操作,但是我越多 n 越多,两个代码之间的时间差就越大。

两种算法的Big O 是相同的,因为第一个算法中的while 循环迭代n 次作为第二个算法中的for 循环,而第一个算法中的嵌套for 循环扫描所有元素作为两个在第二个中嵌套了 while 循环。

这是第一个:

def look_and_say_sequence(first, n):

    while n != 1 :
        
        succ, start, k = '', first[0], 0
        
        for x in first :
            if x != start :
                succ, start, k = succ + str(k) + start, x, 1
            else :
                k = k + 1

        first = succ + str(k) + start
        n -= 1

    return first

look_and_say_sequence('1', 48) # 10 SECONDS 

这是第二个:

def look_and_say_sequence(first, n):    
    
    for _ in range(n-1):
    
        seq, res, ind = first, '', 0
        
        while ind < len(seq):
        
            pending, c = seq[ind], 0
            
            while ind < len(seq) and pending == seq[ind]:
                c += 1; ind += 1
            
            res += "".format(c, pending)
            
    return res

look_and_say_sequence('1', 48) # 2 SECONDS

那么,这两种实现之间怎么可能有 5 的因数呢?

感谢您的帮助!

【问题讨论】:

什么时候让你感到困惑?你做了什么来跟踪算法的复杂性......例如计算循环迭代? 嗯......即使它们的写法不同,它们似乎也有相同的循环,我错了吗? 这不是一个提供“似乎”问题的网站。 Analyze 实现。我们希望您在此处发布之前自行尝试解决方案。 那么,他们肯定有不同的 Big O? 该链接是为您提供分析工具。您尚未提供任何硬数据表明两者具有不同的复杂性。当您将问题集中在这些点上时,您可能会得到答案。 【参考方案1】:

你的减速在于排队

next_element , start , k = next_element + str(k) + start , x , 1

当 next_element 是一个非常长的字符串时,这会导致重大的运行时损失(随着 n 变大,next_element 的长度超过 500k 个字符,n = 48 时肯定会出现这种情况)。尝试运行以下两个脚本:

import time

a = time.time()
s = ''
for i in range(99999):
  s = (s + '1') + '1' # comment this out
  # s += '1' + '1'  # and uncomment this to see the speed difference

b = time.time()
print(b-a)

您会注意到使用 += 的行运行得更快。 Python 从左到右计算,这意味着 (s + '1') 必须在附加 + '1' 之前计算出一个新字符串。这就是增加这么多减速的原因。

fwiw 如果您将问题行更改为

next_element += str(k) + start
start = x
k = 1

您实际上会看到您的***算法运行得更快

【讨论】:

非常感谢!!!要理解的是,为什么看起来只是 sintax 问题的差异会导致运行时间不同 更新了示例以说明为什么 python 会这样,希望这对你有意义

以上是关于为啥看和说序列的这两种实现有不同的执行时间?的主要内容,如果未能解决你的问题,请参考以下文章

`$this` 的这两种用法有何不同?

为啥这两种轮换方法会给我不同的用户体验?

编译器实现

Google App Engine 和 Django 模板:为啥这两种情况不同?

python面向对象的三大特征--多态

为啥 p[:] 在这两种情况下的工作方式不同?