最大公约数_辗转相除法_更相减损术_原理证明

辗转相除法

算法使用

  • 要计算\(a\)\(b\)的最大公约数,且\(a \ ÷ \ b = q \cdots r \ \ \ (a >= b)\).
    • \(r \not = 0\),可将计算\(a\)\(b\)的最大公约数,转为计算\(b\)\(r\)的最大公约数.
    • \(r = 0\),则\(a\)\(b\)的最大公约数为\(b\)

数学原理

\[\begin{aligned} 要证 & \textcolor{blue}{\gcd(a,b) = \gcd(b,r)} \\ & \gcd(x,y)表示x和y的最大公约数 \\ 假设&a \ ÷ \ b = q \cdots r , \ a、b、q、r 均为整数 \\ & \gcd(a,b) = d_1 , \gcd(b,r) = d_2 \\ & a = d_1 \cdot m \ , \ b = d_1 \cdot n , m与n互质 \\ & b = d_2 \cdot i \ , \ r = d_2 \cdot j , i与j互质 \\ \therefore \ & a = b \cdot q + r \\ & r = a - b \cdot q \\ \because \ & r = a - b \cdot q \\ & \ \ = d_1 \cdot m - d_1 \cdot n \cdot q \\ & \ \ = d_1 (m - n \cdot q) \\ \therefore \ & r \ ÷ \ d_1 = m - n \cdot q 为整数 \\ & d_1 是 r 的约数 \\ \therefore \ & \textcolor{orange}{d_1是a、b、r的公约数} \\ \therefore \ & \textcolor{orange}{d_1 <= d_2} \\ \because \ & a = b \cdot q + r \\ & \ \ = d_2 \cdot i \cdot q + d_2 \cdot j \\ & \ \ = d_2(i \cdot q + j) \\ \therefore \ & a \ ÷ \ d_2 = i \cdot q + j 为整数 \\ & d_2 是 a 的约数 \\ \therefore \ & \textcolor{orange}{d_2是a、b、r的公约数} \\ \therefore \ & \textcolor{orange}{d_2 <= d_1} \\ \therefore \ & \textcolor{blue}{d_1 = d_2} \\ & \textcolor{blue}{\gcd(a,b) = \gcd(b,r)} \end{aligned} \]

代码实现

int gcd(int a , int b)
{
    if(a < b) swap(a,b);
    return b > 0 ? gcd(b,a % b) : a;
}

更相减损术

算法使用

  • 要计算\(a\)\(b\)的最大公约数,且\(a >= b\).
    • \(a - b \not = b\),可将计算\(a\)\(b\)的最大公约数,转为计算\(a - b\)\(b\)的最大公约数.
    • \(a - b = b\),则\(a\)\(b\)的最大公约数为\(b\)

数学原理

\[\begin{aligned} 要证 & \textcolor{blue}{\gcd(a,b) = \gcd(b,a - b)} , a > b \\ & \gcd(x,y)表示x和y的最大公约数 \\ 假设 & \gcd(a,b) = d_1 , \gcd(b,a - b) = d_2 \\ & a = d_1 \cdot m \ , \ b = d_1 \cdot n , m与n互质 \\ & a - b = d_2 \cdot i \ , \ b = d_2 \cdot j , i与j互质 \\ \because \ & a - b = d_1(m - n) \\ \therefore \ & \begin{cases} \textcolor{red}{a = d_1 \cdot m} \\ \textcolor{red}{b = d_1 \cdot n} \\ \textcolor{red}{a - b = d_1 \cdot (m - n)} \\ \end{cases} \\ \therefore \ & \textcolor{orange}{d_1是a、b、a-b的公约数} \\ & \textcolor{orange}{d_1 <= d_2} \\ \because \ & a = d_2 (i + j) \\ \therefore \ & \begin{cases} \textcolor{red}{a = d_2 \cdot (i + j)} \\ \textcolor{red}{b = d_2 \cdot j} \\ \textcolor{red}{a - b = d_2 \cdot i} \\ \end{cases} \\ \therefore \ & \textcolor{orange}{d_2是a、b、a-b的公约数} \\ & \textcolor{orange}{d_2 <= d_1} \\ \therefore \ & \textcolor{blue}{d_1 = d_2} \\ & \textcolor{blue}{\gcd(a,b) = \gcd(b,a - b)} \\ \end{aligned} \]

代码实现

int gcd(int a , int b)
{
    if(a == b) return a;
    return gcd(max(a,b) - min(a,b),min(a,b));
}

更相减损术优化

算法使用

  • 要计算\(a\)\(b\)的最大公约数,且\((a >= b)\).
    • \(a \not = b\),
      • \(a \ \% \ 2 = 0\)\(b \ \% \ 2 = 0\),则可将计算 \(\gcd(a,b)\) 转为计算 \(2 *\gcd(a \ \% \ 2,b \ \% \ 2)\) .
      • \(a \ \% \ 2 = 0\)\(b \ \% \ 2 \not = 0\),则可将计算 \(\gcd(a,b)\) 转为计算 \(\gcd(a \ \% \ 2,b)\) .
      • \(a \ \% \ 2 \not = 0\)\(b \ \% \ 2 = 0\),则可将计算 \(\gcd(a,b)\) 转为计算\(\gcd(a , b \ \% \ 2)\) .
      • \(a \ \% \ 2 \not = 0\)\(b \ \% \ 2 \not = 0\),则可将计算 \(\gcd(a,b)\) 转为计算 \(\gcd(a - b , b)\) .
    • \(a = b\),则 \(\gcd(a,b) = a\) .

数学原理

更相减损术在两个整数相差较大时,递归多次影响性能,在此时可以通过简单位运算改善性能

代码实现

int gcd(int a , int b)
{
    if(a == b) return b;
    if(!(a & 1) && !(b & 1)) return gcd(a >> 1,b >> 1) << 1;
    if(!(a & 1) && b & 1) return gcd(a >> 1,b);
    if(a & 1 && !(b & 1)) return gcd(a,b >> 1);
    return gcd(max(a,b) - min(a,b),min(a,b));
}
posted @ 2022-12-30 13:42  WHY139  阅读(82)  评论(0编辑  收藏  举报