博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
扩展欧几里德算法及其应用
阅读量:6243 次
发布时间:2019-06-22

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

  接着欧几里德算法往后写,扩展欧几里德算法常常用来解不定方程及一些相关的应用,用到的思想就是欧几里德算法的思想:通过在结果不改变的情况下不断取余而逐步缩小数据规模,两个数会不断变小,直到减小到一个数是另一个数的倍数的时候,就很容易求出他们的最小公倍数了。下面我们来说说扩展欧几里德的思想:

  我们要求出 a * x + b * y = c 的所有解,其中 a,b,c 是已经告诉你的常数,而 x,y 是待求的未知量,我们要求出所有的 x,y ,其实只要求出一组 x0,y0就行了,剩下的解可以由 x=x0+k*(b*gcd(a,b)/a) , y=y0+k*(a*gcd(a,b)/b)求出,其中 k 为任意整数。

  而怎么求出一组 a * x + b * y = c 的解呢?首先判断是否有解的条件是 c%gcd(a,b) 是否等于 0。也就是说 c一定要是 a,b 的最大公约数的整数倍才有解,否则就没有整数解,这个只要自习想一想就可以理解,所以,我们只要求出  a * x + b * y =  gcd(a,b) 的一组解最后再乘以 c/gcd(a,b) 就好了。接下来我们说怎么求  a * x + b * y =  gcd(a,b)的解。

  到了重头戏,求 a * x + b * y =  gcd(a,b)的解,按照本文开头提到的想法,不断缩小数据规模,首先,在前面证明欧几里得算法的时候我们证明了 gcd(a,b)=gcd(a,a%b),现在我们提出另一个一个方程 b * x1 +a%b * y1 = gcd( b,a%b) ,这里的 a,b,x,y  还是上一个方程的 a,b,x,y ,但是可以看出,这个方程的系数比上一个方程小了,所以只要我们得到这个方程和原方程是解的关系,我们就可以利用这个方程化简数据规模,从而递归地求出方程的解。于是联立两个方程我们得到了 : x= y1; y=x1-a/b*y1;所以我们只要按照这个方法把x1,y1当成新的x,y再次递归下去就可以求出解。当然我们还要说一下递归的终止条件就是 有一个系数为0,这样就可以求出一组目前方程的确定的 x,y了(不是最终解),当然因为a始终大于b所以肯定是b先为0,这样就得到了退出递归的条件。最终得到的x,y就是a * x + b * y =  gcd(a,b)的一组解了。

  代码实现,C++,递归实现,这个是一开始写的,比较容易理解,但是常数大了一些:

1 void Exgcd(int a,int b,int &x,int &y) 2   { 3       if(b==0) 4      { 5         x=1; 6         y=0; 7         return ; 8     } 9     Exgcd(b,a%b,x,y);10     int t=x;11     x=y;12     y=t-a/b*y;13     return ;14  }

  后来在网上看到了另一种写法,这种写法比较好写,常数也小,推荐:

1 void Exgcd(int a,int b,int&x,int&y)     2 {3      if(!b) { x=1,y=0;    return ;}4      Exgcd(b,a%b,y,x);5      y-=a/b*x;6 }

   另外还有非递归的版本,因为写起来太麻烦,也没有递归版本效率高,所以就不写了-_-

  因为上面只是一个裸的函数,是在确定有解的情况下调用的(事实上不管有没有解调用函数后都会返回一组解),而且返回的解也不是最终解,所以我们还可以加一个判断函数来判断是否有解,并将返回的解转化为最终解:

1 int gcd(int a,int b) {
return b? gcd(b,a%b):a;} 2 bool solve_exgcd(int a,int b,int c,int &x,int &y) 3 { 4 int k=gcd(a,b); 5 if(c%k) 6 return false; 7 Exgcd(a,b,x,y); 8 k=c/k; 9 x*=k; y*=k;10 return true;11 }

   好了,扩展欧几里得到这里就讲完了,接下来我们将根据例题来讲解扩展欧几里德的三个应用:(1)解不定方程 (2)求解线性同余方程 (3)求逆元。链接如下:

  如果有什么地方不懂欢迎提问

 

    

 

 

 

  

转载于:https://www.cnblogs.com/Parallels/p/5962600.html

你可能感兴趣的文章
设计模式(26)-----创建型模式-----建造者模式
查看>>
excel读写技术-:ADO.NET 如何读取 Excel
查看>>
纯前端表格控件SpreadJS与Java结合,实现模板上传和下载等功能
查看>>
推荐 5 款超好用的 Chrome 浏览器插件,文末有从别人的电脑移植插件的方法
查看>>
几种实现延时任务的方式(二)
查看>>
ReactNative:require & import
查看>>
MaxCompute新功能发布
查看>>
decorator(修饰器)的业务应用
查看>>
ES6系列-- 8. Symbol
查看>>
要点提炼| Gradle指南
查看>>
Hexo Next底部powered by的logo栏更改以及注意事项(附官方文档,文末有福利链)
查看>>
我是如何进入阿里巴巴的-面向春招应届生Java面试指南(七)
查看>>
Android Studio 打包生成的 apk 安装包装到手机上闪退
查看>>
Mybatis技术内幕:初始化之加载 mybatis-config
查看>>
mysql与pymysql
查看>>
Fastlane(二):结构
查看>>
vue高阶组件
查看>>
Android消息机制Handler源码分析
查看>>
HashMap JDK1 8源码
查看>>
2018年互联网圈,程序员圈竟然脱单的这么多?
查看>>