How to calculate HCF a very large number and a small number without causing stack overflow. I am using euclid algorithm

时间:2017-08-04 12:54:19

标签: c++

I am using Euclid algorithm but it is causing run time error due to stack overflow. I am unable to calculate HCF of a very large number and a small number

2 个答案:

答案 0 :(得分:0)

Correctly implemented algorithm shall use at most log(number) steps, and thus not cause stack overflow. I suppose you use the following algorithm:

gcd(a, 0) = a
gcd(a, b) = gcd(a-b, b)

which looks like this in C++:

int gcd(int a, int b) {
  if (b == 0) {
    return a;
  } else {
    return gcd(std::max(a, b) - std::min(a, b), std::min(a, b));
  }
}

This is not optimal. Instead you shall use the following relation

gcd(a, 0) = a
gcd(a, b) = gcd(b, a mod b)

which looks like this in C++:

int gcd(int a, int b) {
  if (b == 0) {
    return a;
  } else {
    return gcd(b, a % b);
  }
}

This code will actually take only log(ab) steps, and thus not cause stack overflow

Also you may try to enable optimisation: it should allow to collapse both of the functions call into non-recursive versions (as this is a tail recursion). Note that it is not certain if it will increase speed.

As a matter of caution: be careful with the negative numbers, the % operator works incorrectly for them

答案 1 :(得分:0)

I believe you're writing a function like this:

int hcf(int a, int b){
    if (a == 0){
        return b;
    }
    else if (b == 0){
        return a;
    }
    else if (a > b){
        return hcf(b, a - b); // this is subtraction
    }
    else if (a < b){
        return hcf(a, a - b); // this is subtraction
    }
}

...and you're calling it with something like

int q = hcf(100000000, 1);

Well... Without optimisation that will create 1 billion recursion calls. It's definite that your program will run out of stack capacity.

My personally preferred solution is give up recursive methods and use an iterative one. The code can then be simplified to a single loop:

int hcf(int a, int b){
    while(a != 0 && b != 0){
        if (a > b){
            a = a - b;
        }
        else{
            b = b - a;
        }
    }
    if (a == 0){
        return b;
    }
    else{
        return a;
    }
}

If you insist on using recursive methods, replace subtraction with modulus.

    else if (a > b){
->      return hcf(b, a % b); // this is modulus
    }
    else if (a < b){
->       return hcf(a, a % b); // this is modulus
    }