gcd(m,n):代表能够整除m与n的最大正整数
1. 欧几里得算法:Euclid(m,n)
step1:若n=0,返回m,过程结束;否则进入step2
step2:m除以n,将余数赋值给r
step3:将n的值给m,将r的值给n,返回step1
代码实现如下:
int Euclids(int m, int n){
while(n!=0){
int r = m % n;
m = n;
n = r;
}
return m;
}
2. 使用中小学寻找最大公约数的方法
eg:
60 = 2*2*3*5
24 = 2*2*2*3
60与24的最大公约数为12
实现此种方式的步骤大概可以分为:
1. 找到m的所有质因数
2. 找到n所有的质因数
3. 找到二者所有的公因数,并相乘
在已知上面步骤后,接下来需要解决的一个问题是:找质因数。这个目标可以转换为寻找质数。
2.1 埃拉托色尼筛选法(找质数)
通过逐渐筛选2的倍数,3的倍数,5的倍数等来寻找一定范围的所有质数。
这里可能会有一个重复的步骤:m与n的公共倍数会被重复筛选,即对于p的
倍数而言,p*(p-1)、p(p-2)……的倍数都已被筛选,所以筛选可以从p*p开始。
实现代码:
int *Sieve(int n){
int m = 2;
// int data[100];
int *data;
data = new int[n]();
for (int i=2; i<n; i++) {
data[i] = i;
}
for (int i=2; i < sqrt(n); i++){
if(data[i] != 0){
int j = i * i;
while(j < n){
data[j] = 0; // 置0,消去
j += i; // 以i的倍数消去
}
}
}
int j=0;
for(int i=0; i<n; i++){
if(data[i]!=0){
data[j] = data[i];
cout<<data[j]<<" ";
j ++;
}
cout<<endl;
}
return data;
}
2.2 基于Sieve()实现最大公约数
找min(m,n)到所有质数后,只需判断该质数是否同时为m,n的质因数,如果是,将其
相乘即可。
代码实现如下:
int gcd(int m, int n){
if(m<2 || n<2){
return 0;
}
int *data;
int max_a = 1;
int j=0;
int mins = min(m,n);
data = Sieve(mins);
int i = 0;
while(i<data[i]) {
if((m % data[i] == 0) && (n % data[i]==0)){
max_a = max_a * data[i];
m = m/data[i];
n = n/data[i];
}else{
i++;
}
}
return max_a;
}
最后的话:这个到这里就暂时完成了。由于自己的代码能力真的不怎么样,所以先从
简单的算法开始吧,然后最好通过博客把过程记录下来,这样以后忘了还可以看看。
(以前也做过一些算法题,但是好像都忘得一干二净了(>_<),太笨了)希望通过
记录得方式可以记久一点吧~