【C++练习】18.C++求两个整数的最小公倍数(LCM)
目录
- C++求两个整数的最小公倍数(LCM)的方法
- 方法一:利用最大公约数(GCD)计算
- 代码实现
- 方法二:逐次增加法
- 代码实现
- 方法三:质因数分解法
- 代码实现
- 方法比较
- 处理大数和特殊情况
- 改进版GCD方法实现
C++求两个整数的最小公倍数(LCM)的方法
最小公倍数(LCM)是指能够同时被两个数整除的最小的正整数。在C++中,有几种常见的方法可以计算两个整数的最小公倍数。
方法一:利用最大公约数(GCD)计算
这是最常用且高效的方法,基于数学公式:
LCM(a, b) = (a × b) / GCD(a, b)
代码实现
#include <iostream>
#include <algorithm> // 用于std::gcd (C++17及以上)// 计算GCD的函数(如果编译器不支持C++17的std::gcd)
int gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a;
}int lcm(int a, int b) {// 防止乘法溢出,先除以GCDreturn (a / std::gcd(a, b)) * b;// 或者使用自定义的gcd函数:// return (a / gcd(a, b)) * b;
}int main() {int num1, num2;std::cout << "输入两个整数: ";std::cin >> num1 >> num2;std::cout << "LCM(" << num1 << ", " << num2 << ") = " << lcm(num1, num2) << std::endl;return 0;
}
方法二:逐次增加法
这种方法通过逐个测试较大的数的倍数,直到找到能被两个数都整除的数。
代码实现
#include <iostream>int lcm(int a, int b) {int max = (a > b) ? a : b;while (true) {if (max % a == 0 && max % b == 0) {return max;}++max;}
}int main() {int num1, num2;std::cout << "输入两个整数: ";std::cin >> num1 >> num2;std::cout << "LCM(" << num1 << ", " << num2 << ") = " << lcm(num1, num2) << std::endl;return 0;
}
方法三:质因数分解法
将两个数分解质因数,然后取每个质因数的最高幂次相乘。
代码实现
#include <iostream>
#include <map>// 质因数分解函数
std::map<int, int> primeFactors(int n) {std::map<int, int> factors;if (n == 0) return factors;// 处理2的因数while (n % 2 == 0) {factors[2]++;n /= 2;}// 处理奇数因数for (int i = 3; i * i <= n; i += 2) {while (n % i == 0) {factors[i]++;n /= i;}}// 如果剩下的n是质数if (n > 2) {factors[n]++;}return factors;
}int lcm(int a, int b) {if (a == 0 || b == 0) return 0;auto factorsA = primeFactors(a);auto factorsB = primeFactors(b);// 合并两个质因数映射,取每个因数的最大指数for (const auto& pair : factorsB) {if (factorsA[pair.first] < pair.second) {factorsA[pair.first] = pair.second;}}// 计算LCMint result = 1;for (const auto& pair : factorsA) {for (int i = 0; i < pair.second; ++i) {result *= pair.first;}}return result;
}int main() {int num1, num2;std::cout << "输入两个整数: ";std::cin >> num1 >> num2;std::cout << "LCM(" << num1 << ", " << num2 << ") = " << lcm(num1, num2) << std::endl;return 0;
}
方法比较
- GCD方法:最有效,时间复杂度为O(log(min(a, b))),推荐使用。
- 逐次增加法:简单但效率低,时间复杂度为O(max(a, b)),仅适用于小数字。
- 质因数分解法:理论上有用,但实现复杂且效率不如GCD方法,适用于需要质因数分解的场景。
处理大数和特殊情况
在实际应用中,还需要考虑:
- 处理负数(LCM总是正数)
- 处理零(任何数与零的LCM是零)
- 防止整数溢出
改进版GCD方法实现
#include <iostream>
#include <algorithm> // 用于std::gcd
#include <cstdlib> // 用于absint lcm(int a, int b) {if (a == 0 || b == 0) return 0;// 取绝对值a = std::abs(a);b = std::abs(b);// 防止溢出,先除以GCD再相乘return (a / std::gcd(a, b)) * b;
}int main() {int num1, num2;std::cout << "输入两个整数: ";std::cin >> num1 >> num2;std::cout << "LCM(" << num1 << ", " << num2 << ") = " << lcm(num1, num2) << std::endl;return 0;
}
这种方法是最推荐的,因为它高效、简洁且能处理各种边界情况。