1

I am writing a C program to compute (i,j)th element in Pascular Triangle i.e f(n,1) = f(n,n) = n, and f(n,k) = f(n-1,k) + f(n-1,k-1) for 1 < k < n I need to print value modulo 1000000007. The Code follows :

#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;
}

When i give input for example 123456 3 as n & k ( It works fine with smaller integer values like 23 2 or 12 3 as n&k) Error is coming

Unhandled exception at 0x003C3D79 in DummyProject.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x003D2F70).

Any Help is appreciated.

mkkhedawat
  • 1,687
  • 2
  • 17
  • 34

3 Answers3

1

Since you made your returnModPascal function recursive, there must be space on the stack for each recursive call.

For example, if you read in 123456, your call to returnModPascal will end up allocating a stack frame for n = 123456, n = 123455, n = 123454, and so on. There's not nearly enough memory for that.

To fix this, you're going to have to rewrite your function so that you don't end up making this many recursive calls for the larger inputs.

Dennis Meng
  • 5,109
  • 14
  • 33
  • 36
  • What could be the alternative as, To calculate the (i,j)th element i have to call them n times. I mean How to increase the stack size or something. n got max limit as 10^9. How to handle it ? – mkkhedawat Sep 28 '13 at 00:03
  • Increasing the stack size will not help. For the big inputs, all that means is that it takes *longer* to cause a stack overflow; it doesn't actually solve the underlying issue. – Dennis Meng Sep 28 '13 at 00:05
  • Then what could be done ? how will I handle the large input ? Please elaborate your rewriting statement. – mkkhedawat Sep 28 '13 at 00:08
  • You're going to have to find a different way to calculate the answer. A recursive approach isn't going to work for the largest inputs that you're supposed to handle. – Dennis Meng Sep 28 '13 at 00:09
1

The typical stack limits are in some 1000s of KBs. In linux you can use

ulimit -a

to know yours (mine is about 8 MB). Since unsigned long int can go up to (again, assuming gcc) 18446744073709551615 (in 64 bit) or 4294967295 (in 32 bit) [I maybe wrong, See your limits.h], and your one stack frame must be of size 2 words, a stack overflow is quite imminent.

Edit: I see you want an alternative. Have you considered using combinatorics? "Calculate" (i,j)th entry by iCj. By that I mean don't actually find factorials and multiply, but cancel out all the terms you can (integral value will always appear) until only a sequence of integers (mathematical sense) remain. Use modular multiplication (mod 1000000007). Read up about efficient modular multiplication using generator exponents.

PhoenixPerson
  • 272
  • 2
  • 16
0

Look at this line of code:

tempans1=returnModPascal(n-1,k);

You call the recursive function at the very beginning, this means that the function will go till the very end of recursion chain before it gets any chance to further process the input. So if you call this function with a comparatively large input such as 123456, this means that the function will have to "stacked" 12345 times before it finally gets to evaluate the if condition.

You should try reducing the input, or a better alternative is to call the function recursively after if statement.

Vinay Pandey
  • 1,129
  • 3
  • 16
  • 33
  • What could be the alternative as, To calculate the (i,j)th element i have to call them n times. n got max limit as 10^9. How to handle it ? – mkkhedawat Sep 28 '13 at 00:02
  • Also if is there just to make return value less than 10^9+7 , That is not gonna change the no of calls. – mkkhedawat Sep 28 '13 at 00:06
  • There is a technique called `memoisation` in which you can store intermediate results (in your case a `NxN` array would suffice). So in the `while` loop, instead of calling `returnPascal` straight-away, you can look up whether that result already exists in the intermediate results array, if it does, then you take it else you calculate the new results and store it in the array for future use. I will try to find a code sample when I get home. – Vinay Pandey Sep 28 '13 at 00:29