C语言如何利用辗转相除法求最大公约数

 更新时间:2023年08月10日 09:51:44   作者:Sandm *  
这篇文章主要介绍了C语言如何利用辗转相除法求最大公约数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

C语言利用辗转相除法求最大公约数

1. 首先要明确几个概念

最大公约数: 也叫最大公因数,是指俩个或多个整数公有约数中最大的一个。

例如,18 和 24的最大公约数是 6

最小公倍数:除0以外最小的一个公倍数就叫作这几个整数的最小公倍数

例如,18 和 24的最小公倍数是 72

2. 辗转相除法

用除数和余数反复做除法运算,当余数为0时,取当前算式除数为最大公约数

例如:求 1997 和 615 俩个正整数的最大公约数

因为:

1997 % 615 = 152
615 % 152 = 7
152 % 7 = 5
7 % 5 = 2
5 % 2 = 1
2 % 1 = 0

所以,1997 和 615 的最大公约数为 1

3. C语言代码实现

#include <stdio.h>
int main()
{
    int data1 = 0, data2 = 0;
    int m = 0;     //该变量是中间变量,不能放在while函数的内部
    scanf_s("%d %d", &data1, &data2);
    while ((m = data1 % data2) != 0)
    {
        data1 = data2;
        data2 = m;
    }
    printf("最大公约数为%d\n", data2);
    return 0;
}

注意点:

对于求模运算符%,若是分数形式求余数的话,如果分子小于分母,则分子就是余数。

例如:2 % 5 = 0

而当不是分数形式求余数的话,即例如:18 % 24 时,可将 % 左边的内容看成是分子,而 % 右边的内容看成是分母。所以 18 % 24 = 18

这里有一个误区,不能将18 与 24 在都约去 6 的情况下去求它们的余数,所以 18 % 24(3 % 8)= 3 是错误的

而不管是 18 % 24 ,还是24 % 18 。它们的余数均不会成为0

如果知道了俩个数的最大公约数,那么其最小公倍数可以根据公式来确定

即最小公倍数 = 俩个数的乘积 / 最大公约数

C语言求最大公约数常见思路

辗转相除法

辗转相除法又称为欧几里得算法,用于求两数的最大公约数gcd(全称为greatest common divisor)

注意两数必须为非负整数a,b。用法为:用两数中较大的数(a1)除以较小的数(b1),得到余数(r1),再用b1除以r1得到余数r2,之后再用r1除以r2,反复进行,直到最后余数是0为止。最大公约数就是最后式子中的除数。

请看如下举例:

 若用函数gcd(a,b)来表示,即gcd(a,b)=gcd(b,a%b),我们可以这样理解:3887 2231和2231 1656的最大公约数是相等的,依次类推、重复操作。

用表达式可以这样来表示:gcd(3887,2231)=gcd(2231,1656)=gcd(1656,575),直到最后到底gcd(a,b)=gcd(c,0),即gcd(3887,2231)=gcd(23,0)。

这里的c为a和b的最大公约数。

下面来看辗转相除法的图像说明

维基百科动态图

下面看算法实现:

算法实现一

 

代码中的a就相当于上述gcd(a,b)=gcd(c,0)中的c。当然还有利用此原理的其他写法,不过是大同小异,这里就不一一列举了。这里的if语句其实是多余的,因为通过辗转相除完全可以实现两数之间的互换。

算法实现二(函数递归法

 对辗转相除足够熟悉后,可以采用递归的方式,如算法实现三

算法实现三(递归思想)

总之一句话:除数除以余数,直到余数为0为止。

更相减损之术

更相减损之术出自我国《九章算术》,原文是这样的:

可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。

算法过程:大数减小数,得到的差用来替换之前的大数,如此反复,直到得出来的差与上次的减数相等。此时的这个差就是两者的最大公约数。

以 36 24为例(如下图):

 可以这样表示:gcd(36,24)=gcd(24,12),即36 24和24 12的最大公约数是相等的。

下面来看代码实现

 总归一句话:用大数减去小数,知道减数和差相等。

最后,当处理较大的数时,辗转相除法虽然在时间上有明显优势。但是,即使是这样,辗转相除法也同样存在缺陷,其在处理较大的素因数(也叫质因数,就是说一个数是另一个数的因数,本身又是质数,就叫做另一个数的素因数)时,缺陷就会显现出来。

当然,实现求取最大公约数还有很多其他方法,这里只进行了常见思路的讲解。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++ 位图及位图的实现原理

    C++ 位图及位图的实现原理

    位图实际上就是一个数组,因为数组有随机访问的功能,比较方便查找,这个数组一般是整形,今天通过本文给大家分享c++位图的实现原理及实现代码,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • 详解C语言内核中的自旋锁结构

    详解C语言内核中的自旋锁结构

    自旋锁是内核中提供的一种高IRQL锁,用同步以及独占的方式访问某个资源。自旋锁是为了解决内核链表读写时存在线程同步问题。本文将讲解一下自旋锁的简单应用,感兴趣的可以了解一下
    2022-09-09
  • 通过代码实例解析c++ vector常用方法

    通过代码实例解析c++ vector常用方法

    这篇文章主要介绍了通过代码实例解析c++ vector常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • C++实现俄罗斯方块(linux版本)

    C++实现俄罗斯方块(linux版本)

    这篇文章主要为大家详细介绍了linux版本C++实现俄罗斯方块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • C++实现LeetCode(67.二进制数相加)

    C++实现LeetCode(67.二进制数相加)

    这篇文章主要介绍了C++实现LeetCode(67.二进制数相加),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 基于Matlab实现有雪花飘落的圣诞树的绘制

    基于Matlab实现有雪花飘落的圣诞树的绘制

    圣诞节快到了(虽然还有十天),一起来用MATLAB画个简单圣诞树叭~代码几乎取消了全部的循环,因此至少需要17b之后的版本,仅存的循环用来让树旋转起来,让雪花飘落起来,让树顶上的星光摇曳起来~感兴趣的可以试一试
    2022-12-12
  • C语言调用摄像头实现生成yuv未压缩图片

    C语言调用摄像头实现生成yuv未压缩图片

    这篇文章主要为大家详细介绍了C语言如何调用摄像头实现生成yuv未压缩图片,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以参考一下
    2023-11-11
  • C语言百行代码绘制圣诞水晶球

    C语言百行代码绘制圣诞水晶球

    今天就是圣诞节了,本文将再教大家一个圣诞项目——圣诞水晶球,今天这个呢代码不多,但难度会有点。感兴趣的小伙伴可以跟随小编一起学习学习
    2021-12-12
  • OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • NDK 数据结构之队列与栈等的实现

    NDK 数据结构之队列与栈等的实现

    这篇文章主要介绍了NDK 数据结构之队列与栈等的实现的相关资料,希望通过本文大家能理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10

最新评论