我想知道在使用动态查找表时是否可以使用迭代。使用递归,您可以从下到上获得所有必要的查找表数据。我似乎无法掌握如何使用迭代实现相同的操作,而无需进行堆栈并最终重新实现递归。
例如,将我的解决方案带到Project Euler问题#14:
table = {1:1}
def collatz(n):
if n in table:
return table[n]
elif n % 2:
x = 1 + collatz(3*n + 1)
else:
x = 1 + collatz(n/2)
table[n] = x
return x
MAXc = 0
for i in xrange(1,1000000):
temp = collatz(i)
if temp > MAXc:
MAXc = temp
result = i
print result
我们如何使用迭代实现相同的功能?
答案 0 :(得分:1)
迭代算法只计算到达1之前的步数是微不足道的。问题是还要更新所有中间值的缓存。
在这种特殊情况下,存在一种不需要显式堆栈的迭代算法。它使用两次传递:第一次计算总步数,第二次更新缓存。
def next(n):
if n % 2 != 0:
return 3*n + 1
else:
return n/2
def collatz(n):
count = 0
i = n
while i not in table:
count += 1
i = next(i)
count += table[i]
i = n
while i not in table:
table[i] = count
count -= 1
i = next(i)
return table[n]
答案 1 :(得分:0)
类似的东西(在飞行中构建代码,对任何错别字/错误都很抱歉):
def collatz_generator(n):
while n != 1:
n = n & 1 and (3 * n + 1) or n / 2
yield n
def add_sequence_to_table(n, table):
table = table or {1:1}
sequence = list(collatz_generator(n))
reversed = list(enumerate(sequence))[::1]
for len, num in reversed:
if num in table:
break
table[n] = len + 1
return table
def build_table(n):
table = add_sequence_to_table(2)
for n in xrange(3, n):
table = add_sequence_to_table(n, table)
return table
没有建筑表(在妻子希望我阅读的情况下随时打印):
def without_table(n):
max_l, examined_numbers = 0, set()
for x in xrange(2, n):
reversed = list(enumerated(collatz_generator(x)))[::-1]
for num, length in reversed:
if num in examined_numbers:
break
examined_numbers.add(num)
if num <= n: # I think this was a problem requirement.
max_l = max(max_l, length)
这不起作用吗?