在此问题中字典是否可能比Brute Force慢?
问题(来自Project-Euler):
为正整数集定义了以下迭代序列:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
使用上面的规则并从13开始,我们生成以下序列:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
可以看出,该序列(从13开始,在1结束)包含10个术语。虽然尚未证实(Collatz问题),但据认为所有起始数字都以1结束。
哪个起始编号低于一百万,产生最长链?
注意:一旦链条开始,条款允许超过一百万。
代码[暴力]:
我开始使用一个强力程序,它从1到1000000中取每个数字并打印出找到的最长链。
完成需要大约30秒。
# number from 1 to 1000000
num = 0
# longest chain here
maxLength = 0
# number that produce the longest chain
result = 0
while num < 1000000:
num += 1
k = num
# count the current chain pieces
i = 0
while k > 1:
i += 1
if k%2 == 0:
k /= 2
else:
k = k*3 + 1
if maxLength < i:
maxLength = i
result = num
print result
然后我说:“太多时间了!让我们实施字典!”
代码[字典]:
使用词典,每次链结束时,链的起始编号和链片编号都存储在字典中,因此当它找到相同的编号超过一次时,它可以使用与此编号关联的值存储在字典中。
5分钟后我停了下来。
# number from 1 to 1000000
num = 0
# longest chain here
maxLength = 0
# number that produce the longest chain
result = 0
dictionary = {}
while num < 1000000:
num += 1
k = num
i = 0
while k > 1:
# if it processed the number before, it use the shortcut
if str(k) in dictionary.keys():
i += dictionary[str(k)]
break
i += 1
if k%2 == 0:
k /= 2
else:
k = k*3 + 1
# add new shortcut
if not (str(num) in dictionary.keys()):
dictionary[str(num)] = i
if maxLength < i:
maxLength = i
result = num
print result
字典是否可能影响该程序的性能,使其真的很慢?它们不是用于提高性能和加速程序吗?或...是我的代码错误?
谢谢!
答案 0 :(得分:1)
此
if str(k) in dictionary.keys():
# ^^^^^
很糟糕。这会将一组键变为list
!并扫描lineraly(在python3中,它是一个生成器,但几乎同样糟糕)。
你可以说。
if str(k) in dictionary:
这是正确的,在O(1)而不是O(n)!
此外,在python中将事物转换为字符串以将其用作dict
中的键是不必要的。数字很好,所以你可以说:k
你现在所说的str(k)
。