擴(kuò)展歐幾里得算法

歐幾里得算法

文中用 \% 表示求模運(yùn)算, /表示整除, 比如 215\%15=5, 215/15=14
歐幾里德算法(稱輾轉(zhuǎn)相除法),用于計(jì)算兩個(gè)整數(shù)a, b的最大公約數(shù)gcd(a, b).
基本原理

  1. gcd(a, b) = gcd(a, b-a) 與第3條結(jié)合, 可以寫更相減損術(shù)
  2. gcd(a,b) = gcd(b,a\%b) 與第3條結(jié)合, 歐幾里得算法(輾轉(zhuǎn)相除法)
  3. gcd(a, 0) = a
  4. gcd(a, b) 是點(diǎn)集 \{ax+by| x,y \in Z\} 中最小的正整數(shù).
    c/c++ 實(shí)現(xiàn)的歐幾里得算法
int gcd(a, b)
{
    int temp;
    while(b)
    {
          temp = b;
          b = a % b;
          a = temp;
    }
  return a;
}

擴(kuò)展歐幾里得算法

ax+by=gcd(a,b)的整數(shù)解
因?yàn)槲也皇菍W(xué)數(shù)學(xué)的, 嚴(yán)謹(jǐn)?shù)淖C明就不寫了. 只寫一點(diǎn)簡單的推導(dǎo)

遞推公式

設(shè)
ax_1+by_1=gcd(a,b)
bx_2+(a\%b)y_2=gcd(b,a\%b)=gcd(a,b)
\therefore ax_1+by_1=bx_2+(a\%b)y_2=bx_2+(a-a/b*b)y_2
\therefore ax_1+by_1=ay_2+b(x_2-a/by_2)
\begin{cases} x_1=y_2\\ y_1=x_2-(a/b)y_2 \end{cases}
根據(jù)上式的 c++ 實(shí)現(xiàn)

void exgcd(int a, int b, int& g, int& x, int& y)
{  // 純c好像不支持引用, 可以用指針代替.
    if(!b)
    {
        g = a;
        x = 1;
        y = 0;
    }
    else exgcd(b, a % b, g, x, y);
    int t;
    t = x;
    x = y;
    y = t -(a / b) * y;
}

非遞歸算法

這個(gè)稍有些難, 仍然是a,b,g,x,y
step1 . x'=y=1, x=y'=0, c=a, d=b
step2. r=c\%d, q=c/d
step3. if(r==0) 結(jié)束, else繼續(xù)
step4. c=d, d=r,\begin{cases}t=x'\\x'=x\\x=t-qx\end{cases},\begin{cases}t=y'\\y'=y\\y=t-qy\end{cases} 去step2

初始時(shí)由上step1的定義有 \begin{cases}ax+by=d &(1)\\ax'+by'=c&(2)\end{cases}\Rightarrow a(x'-qx)+b(y'-qy)=r\quad (3)
第一次到step3, 如果r=0,x,y就是ax+by=gcd(a,b)的解
step4
(1)式變?yōu)?ax'+by'=c, (3)式變?yōu)?img class="math-inline" src="https://math.jianshu.com/math?formula=ax%2Bby%3Dd" alt="ax+by=d" mathimg="1">

void exgcd(int a, int b, int& g, int& x, int& y)
{ // 可以用來求逆元
    if(!b)
    {
        x = 0;
        y = 1;
        g = a;
    }
    else
    {
          int x1, y1, q, r, t;
          x1 = y = 1; y1 = x = 0; 
          r = a % b; q = a / b;
          while(r) 
          {
              a = b;
              b = r;
              t = x1;
              x1 = x;
              x = t - q * x;
              t = y1;
              y1 = y;
              y = t - q * y;
              r = a % b;
              q = a / b;
          } 
          g = b;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容