最大公约数

#include <bits/stdc++.h>
using namespace std;

int n, m, ans = 1;//n m 表示要约的数 ans调试函数递归用
clock_t  start, finish; //计时器  

//辗转相除法 适用于比较大的数 但是最好不要是高精度 % 的效率比较低
int Gcd_1(int m,int n){
    if(m < n) return Gcd_1(n, m );
    return (n == 0) ? m : Gcd_1(n, m % n);
}

//这个最大公约数的函数更适合高精度的
// m --> 偶数 n -->偶数 gcd(m,n) = gcd(m/2,n/2);
// m --> 偶数 n -->奇数 gcd(m,n) = gcd(m/2,n);
// m --> 奇数 n -->偶数 gcd(m,n) = gcd(m,n/2);
// m --> 奇数 n -->奇数 gcd(m,n) = gcd(n,m-n);
int gcd(int m,int n){
    if(m == n) return m;
    if(m < n) return gcd(n,m);
    if(m & 1 == 0) return (n & 1 == 0)? 2*gcd(m/2,n/2):gcd(m/2,n);
    return (n & 1 == 0) ? gcd(m,n/2):gcd(n,m-n);
}

//gcd 当 m n 为偶数时 有可能会有大量的递归,消耗大量的栈空间,效率有点低
//不过这样改的话就不是很适用于大整数的了,但是比gcd快
int Gcd(int m,int n){
    
    //printf("Gcd[%d] : m = %d n = %d\n",ans++, m , n );
    if(m == n) return m;
    if(m < n) return Gcd(n, m);
    
    if(m & 1 == 0 && n & 1 == 0 ) return Gcd(m / 2, n / 2);
    // n ,m 为偶数的时候直接算成奇数,不必再递归除以 2
    while(m & 1 == 0)  m >>= 1;// m 为偶数
    while(n & 1 == 0)  n >>= 1;// n 为偶数
    
    return Gcd(n, m - n);
}

//运行各自的函数并且计算时间
void text_1(){
    start = clock();  
    cout<<gcd(m,n)<<endl;
    finish = clock();  
    cout<< (double)(finish - start) / CLOCKS_PER_SEC <<endl;
}
void text_2(){
    start = clock();  
    cout<<Gcd_1(m,n)<<endl;
    finish = clock();  
    cout<< (double)(finish - start) / CLOCKS_PER_SEC <<endl;
}
void text_3(){
    start = clock();  
    cout<<Gcd(m,n)<<endl;
    finish = clock();  
    cout<< (double)(finish - start) / CLOCKS_PER_SEC <<endl;
}

int main(){
    cin>>m>>n;
    
   //这三个函数都有不一样的地方
   //数据大小不同运行的效率都有点差异
   text_1();
   text_2();
   text_3();
    return 0;
}
posted @ 2021-02-23 23:43  Carrot_Rui  阅读(90)  评论(0)    收藏  举报