辗转相除法求最大公约数实现思路及代码

辗转相除法

欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。————百度百科

本文不对该算法进行证明,只阐述一下该算法的计算过程和代码实现

  • 问题一:求1997和615两个整数的最大公约数
  1. 1997 / 615 = 3(余152)
  2. 615 / 152 = 4(余7)
  3. 152 / 7 = 21(余5)
  4. 7 / 5 = 1 (余2)
  5. 5 / 2 = 2 (余1)
  6. 2 / 1 = 2 (余0)

此时1为两个整数的最大公约数

  • 问题二:求3139和2117两个整数的最大公约数
  1. 3139 / 2117 = 1(余1022)
  2. 2177 / 1022 = 2 (余73)
  3. 1022 / 73 = 14(余0)

此时73为两个整数的最大公约数

  1. 什么时候停止计算——>循环条件
  • 当一个数除另一个数,余数为0,余数为0的表达式中,73即需要求得的最大公约数
  • 1022 / 73 = 14(余0),余数为0的除数73为所求值
  1. 下一次循环计算的值如何改变——>迭代表达式
  • 上一次循环的除数作为下一次循环的被除数,上一次循环的余数作为下一次循环的除数
  • (不会有人不知道被除数,除数是在前还是在后吧)
  • 被除数的前一个,除数是后一个

明白了上面两个问题之后,接下来要做的就是代码实现了

#include <stdio.h>

int main() {

    int a = 1997, b = 615;

    // 循环条件:当一个数除另一个数,余数为0的时候循环结束,故如果a % b !=0则一直循环
    // 答案:余数为0的表达式中,除数为最大公约数
    while (a % b != 0) {
        // 迭代表达式
        // 该次循环的除数也就是b作为下一次计算的被除数即把b的值赋给a,这一步都能理解a = b;
        int c = a;
        a = b;
        /* 该次循环的余数作为下一次计算的除数也就是----->b = (a % b),看起来好像是这样写没错,但是忽略了一个问题,a在上面一个
           表达式中已经被改变了原先的值*/
        // 故我们需要对原始的变量a的值用另一个变量c进行存储故int c = a;但这个表达式不能写在下方,得写在a = b;的上方,得在a变化前对它进行记录
        // 就从b = (a % b)--------->b = (c % b);
        b = (c % b);
    }
    printf("%d",b);

    return 0;
}
// 运行步骤
/*
                                                1997 / 615 = 3(余152)
                                                615 / 152 = 4(余7)
                                                152 / 7 = 21(余5)
                                                7 / 5 = 1(余2)
                                                5 / 2 = 2(余1)
                                                2 / 1 = 2(余0)
*/
// 如果想要看到运行步骤可以把while后后面的输出改一下
#include <stdio.h>

int main() {

    int a = 1997, b = 615;

    // 循环条件:当一个数除另一个数,余数为0的时候循环结束,故如果a % b !=0则一直循环
    // 答案:余数为0的表达式中,除数为最大公约数
    while (a % b != 0) {
        printf("%d / %d = %d(余%d)\n",a,b,a/b,a%b);
        // 迭代表达式
        // 该次循环的除数也就是b作为下一次计算的被除数即把b的值赋给a,这一步都能理解a = b;
        int c = a;
        a = b;
        /* 该次循环的余数作为下一次计算的除数也就是----->b = (a % b),看起来好像是这样写没错,但是忽略了一个问题,a在上面一个
           表达式中已经被改变了原先的值*/
        // 故我们需要对原始的变量a的值用另一个变量c进行存储故int c = a;但这个表达式不能写在下方,得写在a = b;的上方,得在a变化前对它进行记录
        // 就从b = (a % b)--------->b = (c % b);
        b = (c % b);
    }
    printf("%d / %d = %d(余%d)\n",a,b,a/b,a%b);

    return 0;
}

代码如何实现的,具体思考步骤和写法都已经在注释中阐明

如果有问题,可以私信或者评论区提问

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Likf(❁´◡`❁)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值