C-拓展欧几里得算法-gcd-逆元

最大公因数——递归写法

#include <stdio.h>
int gcd(int a,int b);

int main()
{
    int x,y,x1,y1;
    printf("请输入两个数:\n");
    scanf("%d%d",&x,&y);
    //不论哪个在前都能得到正确结果
    x1 = (x>y)?x:y;
    y1 = (x>y)?y:x;
    printf("公因数是:%d\t",gcd(x1,y1));
}
//递归写法
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}

逆元

#include <stdio.h>
int ExtendedEuclid( int f,int d ,int *result);
int main()
{
    int x,y,z;
    z = 0;
    printf("输入两个数:\n");
    scanf("%d%d",&x,&y);

    if(ExtendedEuclid(x,y,&z))  //设置互素的情况的返回值为1,若不互素返回0
    printf("%d和%d互素,乘法的逆元是:%d\n",x,y,z);
    else
    printf("%d和%d不互素,最大公约数为:%d\n",x,y,z);
    return 0;
}

int ExtendedEuclid( int a,int b ,int *result) //eg: a=26 b=11
{
    int x1,x2,x3;
    int y1,y2,y3;
    int t1,t2,t3;
    int q;

    x1 = y2 = 1;
    x2 = y1 = 0;
    x3 = ( a>=b )?a:b;  // x3 = a = 26
    y3 = ( a>=b )?b:a;  //y3 = b =11 即,保证大的作a,小的作b
    while( 1 )
    {
        if ( y3 == 0 )
        {
            *result = x3; /* 两个数不互素则result为两个数的最大公约数,此时返回值为零 */
            return 0;
        }
        if ( y3 == 1 )
        {
            *result = y2; /* 两个数互素则result为其乘法逆元,此时返回值为1 */
            return 1;
        }
            q = x3/y3;      //商=a/b=26/11=2
            t1 = x1 - q*y1; //t1 = 1-2*0=1
            t2 = x2 - q*y2; //t2 = 0 - 2*1 = -2
            t3 = x3 - q*y3; //余数 t3 = 26 - 2*11 = 4
            x1 = y1;        //x1 = 0
            x2 = y2;        //x2 = 1
            x3 = y3;        //x3 = b = 11,b替换a的位置
            y1 = t1;        //y1 = 1
            y2 = t2;        //y2 = t2 = -2
            y3 = t3;        // y3 = 余数 = 4
    }
}


例子对照

int a,b;
// gcd(a,b) = 1
例子
a = 11 b = 26
answer = 19

26 = 11 * 2 + 4  a=26 b =11
11 = 4 * 2 +3	a=11 b=4 
4 = 3 * 1 + 1  ze a=4 b= 1
3 = 1 * 1		a = 1 b=0
gcd=1

if (a<b){
	while(c!=1){
	c = b % a
	b = a
	a = c
	}
}
print(c)
posted @ 2022-03-15 17:27  Dinesaw  阅读(161)  评论(0编辑  收藏  举报