辗转相除法(gcd)求两个数的最大公约数

辗转相除法求两个数的最大公约数

简介

欧几里得算法又称辗转相除法,是指用于计算两个非负整数 a , b a,b ab的最大公约数(Greatest Common Divisor,简称gcd)。
其基本思想是:以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数。

定理

其计算原理依赖于下面的定理:
定理:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。
设两数 a , b ( a ≥ b ) a,b(a\geq b) abab并用 g c d ( a , b ) gcd(a,b) gcd(a,b)表示 a , b a,b ab的最大公约数, a    m o d    b a\;mod\;b amodb表示 a a a b , b, b,比如 10    m o d    3 = 1 10\;mod\;3=1 10mod3=1,有:
g c d ( a , b ) = g c d ( b , a    m o d    b ) gcd(a,b)=gcd(b,a\;mod\;b) gcd(a,b)=gcd(b,amodb)
比如: g c d ( 25 , 10 ) = g c d ( 10 , 5 ) gcd(25,10)=gcd(10,5) gcd(25,10)=gcd(10,5)

定理证明(选看)

定理证明过程:
c = g c d ( a , b ) c=gcd(a,b) c=gcd(a,b),即 c c c a , b a,b a,b的最大公约数。则有:
a = m c , b = n c ( m ≥ n ≥ 1 且 m , n 互 质 ) ( 1 ) a=mc,b=nc (m\geq n \geq 1且m,n互质)\qquad (1) a=mc,b=nc(mn1mn)(1)
a = k ∗ b + r a=k*b+r a=kb+r,即
a    m o d    b = r , a ÷ b = k a\;mod\;b=r,a\div b=k amodb=r,a÷b=k
a = k ∗ b + r a=k*b+r a=kb+r进行变形:
r = a − k ∗ b = m ∗ c − k ∗ n ∗ c = ( m − k ∗ n ) ∗ c r=a-k*b=m*c-k*n*c=(m-k*n)*c r=akb=mcknc=(mkn)c
接下来只需证明 m − k ∗ n m-k*n mkn n n n 互质即可,这是因为:
b = n ∗ c b=n*c b=nc
r = ( m − k ∗ n ) ∗ c r=(m-k*n)*c r=(mkn)c
根据最大公约数的定义,只要 m − k ∗ n m-k*n mkn n n n 互质,就可以说明 c c c b 和 r b和r br的最大公约数,即:
g c d ( b , c ) = c = g c d ( a , b ) gcd(b,c)=c=gcd(a,b) gcd(b,c)=c=gcd(a,b)
这就是定理的结论。
接下来用反证法证明: m − k ∗ n m-k*n mkn n n n互质
假设 g c d ( n , m − k ∗ n ) = d gcd(n,m-k*n)=d gcdn,mkn=d,即:
n = x ∗ d , m − k ∗ n = y ∗ d n=x*d,m-k*n=y*d n=xd,mkn=yd
则有:
m = y ∗ d + k ∗ n = ( y + k ∗ x ) ∗ d m=y*d+k*n=(y+k*x)*d m=yd+kn=(y+kx)d
又因为 n = y ∗ d n=y*d n=yd
所以 m m m n n n有公约数 d d d,与式 ( 1 ) \qquad (1) (1)矛盾
即证 m − k ∗ n m-k*n mkn n n n 互质,所以定理成立。

展辗转相除法

展辗转相除法就是反复利用该定理,直到 r = 0 r=0 r=0时,对应的 b b b就是两数的最大公约数;
因为 r = 0 r=0 r=0表示 a / b = k ( 余 0 ) a / b=k(余0) a/b=k(0),即 a = k ∗ b a=k*b a=kb,
a , b a,b a,b有最大公约数b。

假如需要求 615 和 152 两个正整数的最大公约数,用辗转相除法计算过程:
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1。
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 615 和 152 的最大公约数 1。

代码

c语言代码

int gcd(int p,int q){
    if(q==0) return p;
    int r=p%q;
    return gcd(q,r);
}

注意事项

这里说明的是调用gcd()函数时的注意事项。
1.调用时不一定要求 p ≥ q p\geq q pq
2. p , q p,q p,q可以是负数,但是一般最大公约数的讨论范围是正整数,结果与都是正数的情况也只是在数值上相等。
3.当有一个参数为0时,结果是另一个参数。

#include<stdio.h>
int gcd(int p, int q) {
	if (q == 0) return p;
	int r = p % q;
	return gcd(q, r);
}
int main()
{
	printf("%d\n",gcd(25, 10));
	printf("%d\n",gcd(10, 25));
	printf("%d\n",gcd(25, -10));
	printf("%d\n",gcd(-25, 10));
	printf("%d\n",gcd(-25, -10));
	printf("%d\n",gcd(0, 10));
	printf("%d\n",gcd(25, 0));
	return 0;
}

输出结果
5
5
5
-5
-5
10
25

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
辗转相除法,又称欧几里德算法,是一种用于个数最大公约数的方法。这个方法的基本原理是将较大的数除以较小的数,然后用除数和余数反复做除法运算,直到余数为0。此时,最后一个除数就是这个数最大公约数。 具体来说,使用辗转相除法最大公约数的表达式为:gcd(a, b) = gcd(b, a % b),其中gcd最大公约数的缩写,a和b是要最大公约数个数,%表示取余操作。 辗转相除法的实现可以使用循环结构来完成。例如,在C语言中,可以使用下面的代码来实现辗转相除法最大公约数: ```c #include <stdio.h> int main() { int m = 0; int n = 0; scanf("%d %d", &m, &n); int r = 0; while (r = m % n) { m = n; // 以除数作为被除数 n = r; // 以余数作为除数 } printf("%d\n", n); // 最后的除数为最大公约数 return 0; } ``` 以上代码可以通过输入个数m和n来它们的最大公约数,并输出结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【算法辗转相除法最大公约数](https://blog.csdn.net/Qiuhan_909/article/details/125941749)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [辗转相除法 (欧几里得算法) 最大公约数](https://blog.csdn.net/MHX_Star/article/details/121898894)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值