zoukankan      html  css  js  c++  java
  • (转)拓展欧几里得算法

    描述:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。

    解法描述:设 a>b, 当 b=0,gcd(a,b)=a,此时 x=1,y=0; ab<>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;
      根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;
      这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
      上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    //全局变量
    int x,y;//希望求出的系数: x*a + y*b= c
    int tmpx,tmpy;
    
    //求最大公约数
    int gcd(int num1, int num2)
    {
        if(0==num2)
        {
            return num1;
        }
        else
        {
            return gcd(num2, num1%num2);
        }
    
    }
    
    void extend_euclid(int a,int b,int c)
    {
        if(0==a)
        {
           x=0;y=1;
           return;
        }
        else if(0==b)
        {
            x=1;y=0;
            return;
        }
        else
        {
            extend_euclid(b,a%b,c);
            tmpx=x;
            tmpy=y;
            x=tmpy;
            y=tmpx-(a/b)*tmpy;
            return;
        }
    }
    
    int main()
    {
        int a,b;//用户输入
        int c;//最大公约数
    
        while(2==scanf("%d %d",&a,&b))
        {
            if(0==a && 0==b)//a,b为不全为0的整数
                return -1;
    
            c=gcd(a,b);
            extend_euclid(a,b,c);
            printf("最大公约数是%d\n",c);
            printf("x=%d, y=%d\n",x,y);
        }
        return 0;
    }
  • 相关阅读:
    Study Plan The TwentySecond Day
    Study Plan The Nineteenth Day
    Study Plan The TwentySeventh Day
    Study Plan The Twentieth Day
    Study Plan The TwentyFirst Day
    python实现进程的三种方式及其区别
    yum makecache
    JSONPath 表达式的使用
    oracle执行cmd的实现方法
    php daodb插入、更新与删除数据
  • 原文地址:https://www.cnblogs.com/Antech/p/2812516.html
Copyright © 2011-2022 走看看