GCD@辗转相除法求最大公约数(欧几里得算法)

/********

辗转相除法的原理:
存在自然数a,b(a > b),求a%b,设a/b = k...d(其中k为整数,d为余数);
那么a = b*k + d;
那么我们可以看作求(b*k + d)与 b 的最大公约数;
显然,b的约数一定是b*k的约数,所以我们要找的最大公约数不应该在b和b*k这两个数之间找,故我们要求的最大公约数就是要找到b跟d的最大公约数,
这点通过一个循环实现,每次判断d是否为零,如果为零,那么上一次循环中作为除数的那个数就是我们要找的最大公约数。(如果不懂,可以对照gcd1部分代码理解)
gcd2函数是后来加的,对于一些已经彻底了解gcd原理的人可以直接拿来用,省时省力;但没有真正了解gcd原理的还是建议先去搞懂,毕竟真正学到的才是自己的。

*********/

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;

int gcd1(int a,int b){
    if(a == 0 || b ==0) return 0; // 任何一方为零,gcd为零
    int r;  //r是一个交换时的第三方变量,无其他含义
    while(b){
        r = b;
        b = a%b;
        a = r;
    }
    return a;
}

int gcd2(int a,int b){
    if(a == 0 || b ==0) return 0;
    
    while(a ^= b ^= a ^= b %= a); //这是gcd函数的核心代码(ababa),最后返回b;这个代码的具体展开式我写在了下面的注释部分,实现原理不做赘述
    /*b = b % a;
    a = a^b;
    b = a^b;
    a = a^b;
    while(a){
        b = b % a;
        a = a^b;
        b = a^b;
        a = a^b;
    }*/
    return b;
}

int main(){
    int a,b;
    while(cin >> a >> b){
        // 如果a < b ,交换a和b
        if(a < b){
            a = a^b;
            b = a^b;
            a = a^b;
        }
        cout << gcd1(a,b) << endl;
        cout << gcd2(a,b) << endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值