博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
欧几里得&扩展算法&扩展欧几里得
阅读量:6113 次
发布时间:2019-06-21

本文共 2189 字,大约阅读时间需要 7 分钟。

欧几里得算法

欧几里得算法又称为辗转相除法  用来计算gcd(a , b)

int gcd(int a , int b){   return a%b==0?b:gcd(b , a%b);}

时间复杂度:O(log(b))

证明如下:

gcd(a,b)=gcd(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个,则有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
扩展算法
算法描述:对于完全不为0的非负整数a , b。gcd(a , b)表示a , b的最大公约数,必然存在整数x , y,使得gcd(a , b) = a*x+b*y。
证明如下:
设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的
原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1= bx2+ (a mod b)y2;
即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
说明: a-[a/b]*b即为mod运算。[a/b]代表取小于a/b的最大整数。
也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
算法实现:
int kuo_zhan(int a , int b , int &x , int &y){    if(b == 0)    {        x = 1;        y = 0;        return a;    }    int q = gcd(b , a%b , y , x);    y -= a/b*x;    return q;}

部分变换:

变换之后实现如下:

int kuoz_zhan_2(int a , int b , int &x , int &y){    if(b == 0)    {        x = 1;        y = 0;        return a;    }    int q = gcd(b , a%b , x , y);    int tmp = x;    x = y;    y = tmp-a/b*y;    return q;}

证明如下:

把这个实现和Gcd的递归实现相比,发现多了下面的x,y过程,这就是扩展欧几里德算法的精髓。
可以这样思考:
对于a'=b,b'=a%b 而言,我们求得 x, y使得 a'x+b'y=Gcd(a',b')
由于b'=a%b=a-a/b*b (注:这里的/是中的)
那么可以得到:
a'x+b'y=Gcd(a',b') ===>
bx+(a - a / b * b)y = Gcd(a', b') = Gcd(a, b) ===>
ay +b(x - a / b*y) = Gcd(a, b)
因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y)
一般解:
上面已经列出找一个 解的方法,在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,p * a+q * b = Gcd(a, b)的其他整数解满足:
p = p0 + b/Gcd(a, b) * t
q = q0 - a/Gcd(a, b) * t(其中t为任意整数)
扩展欧几里得
算法描述:扩展欧几里得可以解决不定方程求解问题,如a*x+b*y=c,其中c=gcd(a , b)时为扩展问题,c不为gcd(a , b)时,需要满足c%gcd(a , b)=0才会有解,否则无解
证明略。
至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(a, b)的每个解乘上 c/Gcd(a, b) 即可,但是所得解并不是该方程的所有解,找其所有解的方法如下:
在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,可以
得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),p * a+q * b = c的其他整数解满足:
p = p1 + b/Gcd(a, b) * t
q = q1 - a/Gcd(a, b) * t(其中t为任意 )
p 、q就是p * a+q * b = c的所有整数解。

转载于:https://www.cnblogs.com/Flower-Z/p/9340342.html

你可能感兴趣的文章
「每日一瞥
查看>>
【随笔】工程师都是性情中人
查看>>
[译] React v16.8: 含有Hooks的版本
查看>>
“寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
查看>>
现代 JavaScript 函数库 usuallyjs 的安装和使用
查看>>
Leaflet-Develop-Guide
查看>>
Android Studio 导入 AOSP 源码
查看>>
React16时代,该用什么姿势写 React ?
查看>>
小程序上传图片到七牛云(支持多张上传,预览,删除)
查看>>
3分钟学会如何调度运营海量Redis系统
查看>>
浅析MySQL事务中的redo与undo
查看>>
iOS开发助手、ipa便捷上传工具!
查看>>
一文了解腾讯云数据库SaaS服务
查看>>
再见,BLE的那些坑!
查看>>
前端杂谈: 如何实现一个 Promise?
查看>>
一个超便捷的豆瓣电影Chrome插件
查看>>
C++ 学习笔记之——字符串和字符串流
查看>>
antd图标的本地化使用
查看>>
Vuejs 实战观书有感 C1
查看>>
UnixBench算分介绍
查看>>