为什么在计算pascal三角形的元素时,我在Recursive C程序中出现Stack Overflow错误?

时间:2013-09-27 23:52:19

标签: c++ c algorithm stack-overflow pascals-triangle

我正在编写一个C程序来计算Pascular Triangle中的第(i,j)个元素 即f(n,1)= f(n,n)= n,并且f(n,k)= f(n-1,k)+ f(n-1,k-1),1 <1。 k&lt; ñ 我需要打印值modulo 1000000007。 该守则如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

unsigned long int returnModPascal(unsigned long int n,unsigned long int k);

int main()
{
    int t;
    unsigned long int ans,n,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lu %lu",&n,&k);
        ans=returnModPascal(n,k);
        printf("%lu",ans);
    }

    return 0;
}

unsigned long int returnModPascal(unsigned long int n,unsigned long int k)
{
    unsigned long int tempans,tempans1,tempans2;
    if(k==1 || k==n)
        tempans=n;
    else
    {
        tempans1=returnModPascal(n-1,k);
        if (tempans1>=1000000007)
            tempans1=tempans1%1000000007;
        tempans2=returnModPascal(n-1,k-1);
        if (tempans2>=1000000007)
            tempans2=tempans2%1000000007;
        if (tempans1+tempans2>=1000000007)
            tempans=tempans1+tempans2-1000000007;
        else
            tempans=tempans1+tempans2;
    }

    return tempans;
}

当我输入例如123456 3作为n&amp; ķ (它适用于较小的整数值,如23 2或12 3为n&amp; k ) 错误即将到来

  

DummyProject.exe中0x003C3D79处的未处理异常:0xC00000FD:   堆栈溢出(参数:0x00000001,0x003D2F70)。

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

由于您的returnModPascal函数是递归的,因此每次递归调用都必须有堆栈空间。

例如,如果您在123456中读到,则对returnModPascal的调用将最终为n = 123456n = 123455n = 123454分配堆栈帧,等等。没有足够的记忆力。

要解决这个问题,你将不得不重写你的函数,这样你就不会为更大的输入进行这么多的递归调用。

答案 1 :(得分:1)

典型的堆栈限制大约是1000s的KB。在linux中你可以使用

ulimit -a

了解你的(我的大概是8 MB)。因为unsigned long int可以达到(再次,假设gcc)18446744073709551615(64位)或4294967295(32位)[我可能错了,请参阅你的limits.h],你的一个堆栈帧必须是2个字的大小堆栈溢出非常迫在眉睫。

编辑:我看到你想要一个替代方案。你考虑过使用组合学吗?通过 i C j “计算”(i,j)条目。我的意思是,实际上并没有找到阶乘和乘法,而是取消所有可能的术语(积分值将始终出现),直到只剩下一系列整数(数学意义)。使用模乘(mod 1000000007)。阅读有关使用生成器指数的高效模块化乘法。

答案 2 :(得分:0)

看看这行代码:

tempans1=returnModPascal(n-1,k);

你在一开始就调用递归函数,这意味着函数将一直运行到递归链的最后才有机会进一步处理输入。因此,如果您使用相对较大的输入(例如123456)调用此函数,则表示该函数在最终评估if条件之前必须“堆叠”12345次。

你应该尝试减少输入,或者更好的选择是在if语句后递归调用函数。