扩展欧几里得算法

扩展欧几里得算法用于:
1.求不定方程
2.求解模的逆元

3.求解同余方程

/*
 * 扩展欧几里得算法(extended Euclidean algorithm)
 * 扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式:
 * ax+by = gcd(a, b) = d(解一定存在,根据数论中的相关定理)。
 * 扩展欧几里德常用在求解模线性方程及方程组中。
 *
 */

#include <stdio.h>

// 递归法实现扩展欧几里德算法
long exgcd1(long a, long b, long *x, long *y)
{
    if(b==0) {
        *x=1;
        *y=0;
        return a;
    }

    long r = exgcd1(b, a%b, x, y);
    long t = *x;
    *x = *y;
    *y = t - a / b * *y;

    return r;
}

// 递推法实现扩展欧几里德算法(正解)
long exgcd2(long a, long b, long *x, long *y)
{
    long x0=1, y0=0, x1=0, y1=1;
    long r, q;
    *x=0;
    *y=1;

    r = a % b;
    q = (a - r) / b;
    while(r)
    {
        *x = x0 - q * x1;
        *y = y0 - q * y1;
        x0 = x1;
        y0 = y1;
        x1 = *x;
        y1 = *y;

        a = b;
        b = r;
        r = a % b;
        q = (a - r) / b;
    }
    return b;
}

int main(void)
{
    long x, y;

    printf("a=%d, b=%d, x=%ld, y=%ld exgcd=%ld\n", 42, 70, x, y, exgcd1(42, 70, &x, &y));

    printf("a=%d, b=%d, x=%ld, y=%ld exgcd=%ld\n", 42, 70, x, y, exgcd2(42, 70, &x, &y));

    return 0;
}


关键代码(正解):

// 递推法实现扩展欧几里德算法(正解)
long exgcd2(long a, long b, long *x, long *y)
{
    long x0=1, y0=0, x1=0, y1=1;
    long r, q;
    *x=0;
    *y=1;

    r = a % b;
    q = (a - r) / b;
    while(r)
    {
        *x = x0 - q * x1;
        *y = y0 - q * y1;
        x0 = x1;
        y0 = y1;
        x1 = *x;
        y1 = *y;

        a = b;
        b = r;
        r = a % b;
        q = (a - r) / b;
    }
    return b;
}



你可能感兴趣的:(数论,exgcd,扩展欧几里德算法)