为啥看和说序列的这两种实现有不同的执行时间?
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 会这样,希望这对你有意义以上是关于为啥看和说序列的这两种实现有不同的执行时间?的主要内容,如果未能解决你的问题,请参考以下文章