zoukankan      html  css  js  c++  java
  • 辗转相除法

    很多人都在用这种方法求最大公约数,但是知道为什么这样能求最大公约数的人就不多了。其实这是一个数论的定理:

    y = ax + b => gcd(x, y) = gcd(b, x) (a, b, x, y ∈ Z)

    只要证明了这个式子成立,只需要证明x、y的公约数和b、x的公约数相同即可,因为如果他们的约数都相同了,那么其中一定有一个是最大的。

    首先介绍一些简单的数学知识:

    y = ax(a, x, y ∈ Z),就说x能整除y,记作x|y

    x|y, x|z => x|ax + bz(这个定理很简单就不做证明了)

    算法的证明如下

    设d|x, d|y

    d|x, d|y => d|y-ax 即 d|b

    所以有d|x, d|y => d|x, d|b

    即x、y的约数都是b、x的约数

     

    假定x,y ∈ Z,x >= y, 令r[0] = x , r[1] = y 用辗转相除法有:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    r[0] = r[1] * q[1] + r[2]    0<=r[2]<r[1]
          
    r[1] = r[2] * q[2] + r[3]    0<=r[3]<r[2]
          
                .
          
                .
          
                .
          
    r[n-2] = r[n-1] * q[n-1] + r[n]    0<=r[n]<r[n-2]
          
    r[n-1] = r[n]q[n]

     

    在序列x=r[0]>r[1]>r[2]...>=0中最多有a项,最终余数为0

    由y = ax + b => gcd(x, y) = gcd(b, x) (a, b, x, y ∈ Z)

    gcd(x, y) = gcd(r[0], r[1]) = gcd(r[1], r[2])=...=r[n]

    即:gcd(x, y )为辗转相除法中组后一个非0的余数

     

    证明

    简单的想法

    设两数为a、b(a>b),求a和b最大公约数(a,b)的步骤如下:用b除a,得a÷b=q......r1(0≤r1)。若r1=0,则(a,b)=b;若r1≠0,则再用r1除b,得b÷r1=q......r2 (0≤r2).若r2=0,则(a,b)=r1,若r2≠0,则继续用r2除r1,……如此下去,直到能整除为止。其最后一个非零除数即为(a,b)。

    原理及其详细证明

    设两数为a、b(b<a),用gcd(a,b)表示a,b的最大公约数,r=a mod b 为a除以b以后的余数,k为a除以b的商,即a÷b=k.......r。辗转相除法即是要证明gcd(a,b)=gcd(b,r)。
    第一步:令c=gcd(a,b),则设a=mc,b=nc
    第二步:根据前提可知r =a-kb=mc-knc=(m-kn)c
    第三步:根据第二步结果可知c也是r的因数
    第四步:可以断定m-kn与n互素【否则,可设m-kn=xd,n=yd,(d>1),则m=kn+xd=kyd+xd=(ky+x)d,则a=mc=(ky+x)dc,b=nc=ycd,故a与b最大公约数成为cd,而非c,与前面结论矛盾】
    从而可知gcd(b,r)=c,继而gcd(a,b)=gcd(b,r)。
    证毕。
    附上一个简单的C++程序的实现:
    View Code
     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 
     7 {
     8     int a,b;
     9     cout<<"请输入两个正整数:"<<endl;
    10     cin>>a;
    11     cin>>b;     //输入两个要求公约数的整数
    12 
    13     int i,j;
    14     int temp;
    15 
    16     if(a>b)    {i=a;j=b;}   //通过if语句来计算出除数和被除数
    17     else       {i=b;j=a;}
    18     
    19     while(j!=0)  //辗转相除法来计算最大公约数
    20     {
    21         temp=i%j;
    22         i=j;
    23         j=temp;
    24     }
    25 
    26 cout<<"两个数的最大公约数为:"<<i<<endl;
    27 
    28 return 0;
  • 相关阅读:
    JS中location.search和setTimeout()和 setInterval()
    javascript的AJAX和Serialize(),解码
    php的变量和基本语法
    isnan
    Urllib 库的基础和实用(2)
    urllib 库的基础和实用(1)
    python获取网页精准爬取数据
    eclipse配置
    搭建JAVA WEB开发环境(tomcat)
    JDK环境变量配置
  • 原文地址:https://www.cnblogs.com/yuanbolin/p/2972369.html
Copyright © 2011-2022 走看看