Итак, я написал программу, которая использует алгоритм евклида, чтобы найти GCD's 2 ints.Загадочный переполнение стека
Пользователь вводит один int (n), тогда программа принимает все возможные комбинации целых чисел между 8 и n, находит их соответствующие GCD (рекурсивно) и печатает, какие вычисления GCD требовали большинства операций модуля.
Я получил программу, работающую, но я получаю переполнение стека около п = 50, и он должен работать, по крайней мере, 3000.
Я рассмотрел мой код на некоторое время и не могу найти проблему ,
#include<iostream>
#include <math.h>
using namespace std;
int cost, gcd, greatestCost, n, beginningA, beginningB, finalA, finalB, finalGCD, iteration;
void findGCD(int num1, int num2, int startingCost) {
//findGCD
//finds GCD of every combination (a,b) from i to n
//prints those with the greatest number of modulus operations
int a = num1;
int b = num2;
cost = startingCost;
cost++;
if (b%a > 0) {
//cout << "gcd(" << b << "," << a << ") = ";
findGCD(b%a, a, cost);
}
else {
gcd = a;
if (cost > greatestCost) {
greatestCost = cost;
finalA = beginningA;
finalB = beginningB;
finalGCD = gcd;
}
//cout << "gcd(" << b << "," << a << ") = " << gcd << " With a cost of: " << cost << endl;
//do next iteration (2,8), (3,8) etc...
if (++beginningA <= beginningB) { //beginning A goes from 1-i first
findGCD(beginningA, beginningB, 0);
}
else {
if (beginningA <= n) { //begin next cycle with new b value (1,9), (2,9) while b <= n
beginningA = 1; //reset to 1 so it will increment from 1-i again
cout << "At i=" << iteration++ << "; gcd(" << finalA << "," << finalB << ") = " << finalGCD <<
" took " << greatestCost << " modulus operations" << endl;
findGCD(beginningA, ++beginningB, 0);
}
else //When it tries to continue iterating with a number > n
//print the last, most intensive, iteration and stop
cout << "At i=" << iteration++ << "; gcd(" << finalA << "," << finalB << ") = " << finalGCD <<
" took " << greatestCost << " modulus operations" << endl;
}
}
}
int main() {
greatestCost = 0; //cost of the iteration with the most modulus operations
beginningA = 1;
beginningB = 8;
iteration = 8;
cout << "Enter an integer greater than 8 " << endl; //receive n from user
cin >> n;
if (n <= beginningB) //begin GCD search, granted user input > 8
cout << "Error!!! integer must be greater than 8";
else
findGCD(beginningA, beginningB, 0); //algorithm begins at (1,8)
return 0;
}
На данный момент единственное, что я могу думать, как проблема является то, что я сделал в C++, что я не должен (я новичок в C++ и передается по от Явы)
Что я пробовал:
- расщепление функции НОД в 2
- передавая только ссылки с помощью Функции
Я бы предположил, что причиной является безудержная рекурсия. Также ваш код для вычисления GCD выглядит тоже ... много. –
мой код для вычисления gcd составляет около 4 строк. остальное связано с чем-то другим. Как исправить беглую рекурсию? – Darren
Затем разделите его на функцию. Также попытайтесь избавиться от всех этих глобальных переменных. Вы рекурсивно пытаетесь вычислить GCD всех возможных комбинаций целых чисел от 8 до 'n'? С 'n = 58', то есть около 2500 рекурсивных вызовов, каждый из которых строит фрейм стека (скажем, около 20 байт, чтобы быть оптимистичным) ... это 50000 байт ... это намного выше любого разумного предела стека. Решение: не рекурсивно, используйте петли. (C++ не гарантирует оптимизацию хвостового вызова, и ваши вызовы не находятся в хвостовом положении в любом случае) –