迭代转换的递归

时间:2013-04-12 15:07:16

标签: optimization recursion iteration pseudocode

知道每个递归函数都可以转换为迭代版本。有人可以帮我找到这个伪代码的迭代版本吗?我试图优化代码和递归显然不是要走的路

sub calc (a, b )
{
    total = 0;
    if(b <= 1) 
        return 1
    if( 2*a > CONST)
        for i IN (1..CONST)
            total += calc(i, b-1) ;
    else
        for j IN (2*a..CONST)
            total += calc(j, b-1) ;
    return total;
}
CONST = 100;
print calc (CONST,2000);

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

从递归到迭代的重构不是解决你的性能问题的答案。该算法从缓存中获益最多,与Fibonacci序列的方式大致相同。

在F#中编写一个简短的测试程序后,包含一些示例数据(CONST = 5a = 0..10b = 2..10):

  • 原始程序耗时6.931秒
  • 缓存版本耗时0.049秒

解决方案是使用tuple(a,b)键保留字典,并在计算之前查找值。这是带缓存的算法:

dictionary = new Dictionary<tuple(int, int), int>();

sub calc (a, b )
{
    if (dictionary.Contains(tuple(a,b)))
        return dictionary[tuple(a,b)];
    else
    {
        total = 0;
        if(b <= 1) 
            return 1
        if( 2*a > CONST)
            for i IN (1..CONST)
                total += calc(i, b-1);
        else
            for j IN (2*a..CONST)
                total += calc(j, b-1);

        dictionary[tuple(a,b)] = total;
        return total;
    }
}

编辑:只是为了确认我的测试的迭代性质不会导致性能提升,我再次尝试使用一组参数(CONST = 5a = 6,{ {1}})。

  • 缓存版本耗时0.034秒
  • 原始版本仍在运行...(2分钟以上)

答案 1 :(得分:0)

只有尾递归算法可以转换为迭代算法。您提供的代码绝对不是尾递归的,因此无法轻松转换为迭代形式。

您的效果问题的解决方案是Memoization