需要动态查找表时的迭代与递归

时间:2014-02-01 23:39:40

标签: python recursion iteration theory

我想知道在使用动态查找表时是否可以使用迭代。使用递归,您可以从下到上获得所有必要的查找表数据。我似乎无法掌握如何使用迭代实现相同的操作,而无需进行堆栈并最终重新实现递归。

例如,将我的解决方案带到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

我们如何使用迭代实现相同的功能?

2 个答案:

答案 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)

这不起作用吗?