Вычислить наибольший общий делитель двух целых чисел. Дополнительные свойства Алгоритм Ограничение алгоритма Реализация #include "iostream" using namespace std; int gcd(int u, int v); int main() { int u; int v; cout << "Numbers should lay in [0; MAXINT] interval." << endl; cout << "Enter 1st number: " << endl; cin >> u; if (u < 0) { cout << "Incorrect value." << endl; cout << "Press any key to exit." << endl; system("PAUSE"); exit(1); } cout << "Enter 2nd number: " << endl; cin >> v; if (v < 0) { cout << "Incorrect value." << endl; cout << "Press any key to exit." << endl; system("PAUSE"); exit(2); } cout << "Greatest common dividor is: " << gcd(u, v) << endl; system("PAUSE"); return 0; } int gcd(int u, int v) { int shift; /* НОД(0, n) = n; НОД(m, 0) = m. */ if (u == 0 || v == 0) return u | v; /* Если m, n чётные, тогда НОД(m, n) = 2 * НОД(m / 2, n / 2). Пусть shift := lg K, где K наибольшая степень 2 такая, что оба числа целиком делятся на 2 в степени K. */ for (shift = 0; ((u | v) & 1) == 0; ++shift) { u >>= 1; v >>= 1; } // Если m чётное, тогда НОД(m, n) = НОД(m / 2, n). while ((u & 1) == 0) u >>= 1; /* Далее считается, что u нечетное. */ do { while ((v & 1) == 0) /* Если n чётное, тогда НОД(m, n) = НОД(m, n / 2). */ v >>= 1; /* Далее считается, что u и v нечетные. Следовательно, u - v четно. Пусть u = min(u, v), v = (u - v) / 2. */ if (u < v) /* Если m, n нечётные и m < n, тогда НОД(m, n) = НОД(n - m, m). */ { v -= u; } else /* Если m, n нечётные и m > n, тогда НОД(m, n) = НОД(m - n, m). */ { int diff = u - v; u = v; v = diff; } v >>= 1; } while (v != 0); return u << shift; } Пример работы программы Анализ алгоритма Таким образом, операции деления и умножения отсутствуют, что позволяет алгоритму быть крайне эффективным по времени выполнения.
Ключевые слова:
бинарный алгоритм нахождения НОД, бинарный алгоритм Евклида, наибольший общий делитель
|
|||||||