我写了一个代码来查找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
答案 0 :(得分:1)
您的代码的两个版本不会以相同的方式计算结果,因此它们花费不同的时间并不会太令人意外。
当您使用if
/ elif
/ else
时,您通常会多次计算相同的next
值。例如,六个可以计算为2*3
或3*2
。由于当i2
是i3
,i5
,{{{{}}的最小值时,6
,n2
,n3
值中只有一个会增加1}},您最终会在第一次传递时选择n5
增加,然后在第二次传递时选择i2
,因为i3
仍为6。 n3
检查将阻止重复值在输出中结束,但您仍需要额外运行循环体。
当您使用多个if next != ugly[count-1]:
时,生成最小if
值的所有i
值将同时递增。这意味着你只会计算一次丑陋的数字,即使它可以通过几种不同的方式生成。避免额外工作意味着代码运行得更快。您也可以删除n
保护代码,因为您永远不会重复生成相同的值。
答案 1 :(得分:1)
不确定是否可以解释,但在我看来,你想要最快的方法和你的代码
min
执行函数调用+循环+比较这是一个很多的测试。特别为3个值调用min
是过度的。
我在没有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
,因为它是内置函数