两个整数的最大公约数
1. 欧几里得算法
gcd(m,n)=gcd(n,m mod n)
假设x是m,n的最大公约数,且m大于n(m小于n时,上式实现两个数的交换)
m=(m/n)*n+m%n(
/
表示整除)n=(n/x)*x
则,则(m/n)*n有约数x,又m有约数x,则m%n也可以被x整除
#include <iostream>
using namespace std;
int Euclid(int m, int n)
{
while (n)
{
int t = m % n;
m = n;
n = t;
}
return m;
}
int main()
{
cout << Euclid(60, 24) << endl;
}
2. 连续整数检测算法
从m、n中较小的数开始查找,直到找到可以被m、n都整除的数
#include <iostream>
using namespace std;
int gcd(int m, int n)
{
int t = min(m, n);
while (m % t != 0 || n % t != 0)
--t;
return t;
}
int main()
{
cout << gcd(60, 24) << endl;
}
3. 求m、n的质因数
求不大于整数n的连续质数序列:
#include <iostream>
#include <vector>
using namespace std;
//埃拉托色尼筛选法,产生一个不大于给定整除n的连续质数序列
void Sieve(int n, vector<int> &isPrime)
{
for (int i = 2; i * i <= n; ++i)
{
if (isPrime[i])
{
int t = i * i;
while (t <= n)
{
isPrime[t] = 0;
t = t + i;
}
}
}
}
int gcd(vector<int> &isPrime, int m, int n)
{
int result = 1;
for (int i = 2; i <= n; ++i)
{
//如果i是质数
if (isPrime[i])
{
while (m % i == 0 && n % i == 0)
{
m = m / i;
n = n / i;
result *= i;
}
}
}
return result;
}
int main()
{
int m, n;
cin >> m >> n;
vector<int> isPrime(min(m, n) + 1, 1); //记录较小数的质数序列
// cout << isPrime.size() << endl;
Sieve(min(m, n), isPrime);
cout << gcd(isPrime, max(m, n), min(m, n)) << endl;
}