将加泰罗尼亚递归算法转换为迭代算法

时间:2011-05-17 21:14:30

标签: algorithm complexity-theory catalan

大家都是黑客,数学家和编码员!

我努力为下面的加泰罗尼亚数字方程创建一个递归算法

C(n)=ΣC(i-1)C(n-i)(使用斯特林数或其他形式简化此等式不是一种选择..)

到目前为止,这是递归算法:

int Cval[1024];//1024 just for example

int C( int n )
    {
    if( Cval[n] ) != ­1 ) return Cval[n];
        int ans = 0;
        if( n == 0 ) ans = 1;
        for( int i = 1; i <= n; i++ )
            ans += C( i ­- 1 ) * C( n ­- i );
                return Cval[n] = ans;
    }

int main()
{
    for( int i = 0; i < 1024; i++ ) Cval[i] = ­1;
    // call C(n) for any n up to 1023
}

现在,我正在尝试将其转换为迭代算法..我需要你的宝贵帮助;)任何想法?

2 个答案:

答案 0 :(得分:0)

创建一个C编号数组,然后进行构建。它实际上比递归版本(它将多次计算大多数数字)的处理更少,并且占用更少的空间(因为数组在连续的内存中而不是通过调用堆栈展开)。

这样做的另一个好处是,您可以缓存结果以进行有效处理。

答案 1 :(得分:0)

您正在尝试实施一种称为Dynamic Programming的更一般的模式。

您使用的缓存机制有时称为自上而下的动态编程,因为您首先从最大的N开始计算。 (顺便说一下,在你的主要部分,你只需要为最大的N调用C(),因为加泰罗尼亚数字的规则使它以递归方式调用所有其他值。)

为了将此算法转换为自下而上(迭代方法),您需要找到参数的排序,使C(x)仅依赖于小于x的元素。通过按此顺序计算C的值,您始终可以直接使用数组值,而不必依赖于记忆功能:

//initialize your base cases by hand, in 
Cval[0] = 1

//Now handle the inductive cases:
for n from 1 up to N:
    Cval[n] = 0
    for i from 1 to n:
        Cval[n] += Cval[i -1] * Cval[n -i];
    // i-1 and n-i are both less than n, so we know that
    // Cval has already been calculated for them.