我写了一个代码来找到ugly numbers。在尝试加快速度的同时,我发现使用3个IF代替IF-ELIF-ELSE使我的代码更快。我尝试运行n的多次迭代的代码,并发现大多数情况下这是真的。
我觉得IF-ELIF-ELSE应该更快,因为如果满足其中一个条件,它就不会进入其他条件。但我无法找到实际发生的任何逻辑。
这是代码:
ugly = [0]*n
ugly[0] = 1
i2, i3, i5 = 0, 0, 0
count = 1
while count<n:
n2 = ugly[i2]*2
n3 = ugly[i3]*3
n5 = ugly[i5]*5
next = min(n2, n3, n5)
if next==n2:
i2 += 1
elif next==n3:
i3 += 1
else:
i5 += 1
if next != ugly[count-1]:
ugly[count] = next
count += 1
您的代码的两个版本不会以相同的方式计算结果,因此它们花费不同的时间不应该太大。
当你使用if
/ elif
/ else
时,你经常会多次计算相同的next
值。例如,六个可以计算为2*3
或3*2
。因为当i2
是i3
,i5
,6
的最小值时,只有n2
,n3
,n5
值中的一个会增加,所以你最终会在第一次传球时选择i2
增加,然后在第二次传球时选择i3
,因为n3
还是六点。 if next != ugly[count-1]:
检查将阻止重复值在输出中结束,但您仍需要额外运行循环体。
当您使用多个if
s时,生成最小i
值的所有n
值将同时递增。这意味着你只会计算一次丑陋的数字,即使它可以通过几种不同的方式生成。避免额外工作意味着代码运行得更快。您也可以摆脱if next != ugly[count-1]:
保护代码,因为您永远不会重复生成相同的值。
不确定能够解释,但在我看来,你想要最快的方法和你的代码
min
执行函数调用+循环+比较这是很多测试。特别要求min
获得3个值是过度的。
我已经重写了没有min
的循环(如果值相等,min
返回最左边的参数,作为Python 2的实现细节,现在保证用于python 3)仅使用不等式测试(链接运算符)
while count<n:
n2 = ugly[i2]*2
n3 = ugly[i3]*3
n5 = ugly[i5]*5
if n5 >= n2 <= n3:
next = n2
i2+=1
elif n5 >= n3 <= n2:
next = n3
i3 += 1
else:
next = n5
i5 += 1
# below: not changed
if next != ugly[count-1]:
ugly[count] = next
count += 1
由于只有3个数字可供比较,因此这样的测试速度更快。
对于我机器上的n=2000000
:
当然,这两个代码都会产生相同的结果。
请注意,我不会调用我的变量next
,因为它是一个内置函数