【C++练习】17.C++求两个整数的最大公约数(GCD)
·
目录
- C++求两个整数的最大公约数(GCD)方法
-
- 1. 辗转相除法(欧几里得算法)
-
- 迭代实现
- 递归实现
- 2. 更相减损术
-
- 实现代码
- 3. 使用STL中的gcd函数
- 4. 二进制GCD算法(Stein算法)
- 性能比较
-
- 完整示例
C++求两个整数的最大公约数(GCD)方法
在C++中,计算两个整数的最大公约数(GCD)有多种方法,下面我将介绍几种常见的方法及其实现。
1. 辗转相除法(欧几里得算法)
这是最经典且高效的GCD计算方法,基于以下数学原理:
gcd(a, b) = gcd(b, a % b)
迭代实现
int gcd_iterative(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
递归实现
int gcd_recursive(int a, int b) {
if (b == 0) return a;
return gcd_recursive(b, a % b);
}
2. 更相减损术
这是中国古代的算法,原理是:
gcd(a, b) = gcd(a-b, b) (当a > b时)
实现代码
int gcd_subtraction(int a, int b) {
while (a != b) {
if (a > b) {
a -= b;
} else {
b -= a;
}
}
return a;
}
3. 使用STL中的gcd函数
C++17标准在
""头文件中提供了
"std::gcd"函数:
#include <numeric>
#include <iostream>
int main() {
int a = 56, b = 98;
std::cout << "GCD is " << std::gcd(a, b) << std::endl;
return 0;
}
4. 二进制GCD算法(Stein算法)
这是一种更高效的算法,特别适合计算机实现,避免了耗时的取模运算:
int gcd_binary(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
int shift = 0;
while (((a | b) & 1) == 0) {
a >>= 1;
b >>= 1;
++shift;
}
while ((a & 1) == 0) {
a >>= 1;
}
do {
while ((b & 1) == 0) {
b >>= 1;
}
if (a > b) {
std::swap(a, b);
}
b -= a;
} while (b != 0);
return a << shift;
}
性能比较
- 欧几里得算法(辗转相除法)通常是最快的,特别是对于大数
- 更相减损术在大数情况下效率较低
- 二进制GCD算法避免了取模运算,在某些平台上可能更快
完整示例
#include <iostream>
#include <numeric> // 用于std::gcd
// 辗转相除法(迭代)
int gcd_iterative(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// 辗转相除法(递归)
int gcd_recursive(int a, int b) {
return b == 0 ? a : gcd_recursive(b, a % b);
}
// 更相减损术
int gcd_subtraction(int a, int b) {
while (a != b) {
if (a > b) a -= b;
else b -= a;
}
return a;
}
// 二进制GCD算法
int gcd_binary(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
int shift = 0;
while (((a | b) & 1) == 0) {
a >>= 1;
b >>= 1;
++shift;
}
while ((a & 1) == 0) a >>= 1;
do {
while ((b & 1) == 0) b >>= 1;
if (a > b) std::swap(a, b);
b -= a;
} while (b != 0);
return a << shift;
}
int main() {
int a = 56, b = 98;
std::cout << "Numbers: " << a << ", " << b << std::endl;
std::cout << "GCD (iterative): " << gcd_iterative(a, b) << std::endl;
std::cout << "GCD (recursive): " << gcd_recursive(a, b) << std::endl;
std::cout << "GCD (subtraction): " << gcd_subtraction(a, b) << std::endl;
std::cout << "GCD (binary): " << gcd_binary(a, b) << std::endl;
// C++17标准方法
#if __cplusplus >= 201703L
std::cout << "GCD (std::gcd): " << std::gcd(a, b) << std::endl;
#endif
return 0;
}
在实际应用中,推荐使用欧几里得算法(辗转相除法)或C++17的
"std::gcd"函数,因为它们既高效又简洁。
更多推荐

所有评论(0)