C語言復習---獲取最大公約數(輾轉相除法和更相減損法)


源自:百度百科 

輾轉相除法

輾轉相除法:輾轉相除法是求兩個自然數的最大公約數的一種方法,也叫歐幾里德算法

例如,求(319377):
∵ 319÷377=0(余319)
∴(319377)=(377319);
∵ 377÷319=1(余58)
∴(377319)=(31958);
∵ 319÷58=5(余29)
∴ (31958)=(5829);
∵ 58÷29=2(余0)
∴ (5829)= 29;
∴ (319377)=29

用輾轉相除法求幾個數的最大公約數,可以先求出其中任意兩個數的最大公約數,再求這個最大公約數與第三個數的最大公約數,依次求下去,直到最后一個數為止。最后所得的那個最大公約數,就是所有這些數的最大公約數。

更相減損法

第一步:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步。
第二步:以較大的數減較小的數,接着把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。
則第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。
其中所說的“等數”,就是最大公約數。求“等數”的辦法是“更相減損”法。所以更相減損法也叫等值算法。
例1.用更相減損術求98與63的最大公約數。
解:由於63不是偶數,把98和63以大數減小數,並輾轉相減:
98-63=35
63-35=28
35-28=7
28-7=21
21-7=14
14-7=7
所以,98和63的最大公約數等於7。
這個過程可以簡單的寫為:
(9863)=(3563)=(3528)=(728)=(721)=(714)=(77)=7.
例2.用更相減損術求260和104的最大公約數。
解:由於260和104均為偶數,首先用2約簡得到130和52,再用2約簡得到65和26。
此時65是奇數而26不是奇數,故把65和26輾轉相減:
65-26=39
39-26=13
26-13=13
所以,260與104的最大公約數等於13乘以第一步中約掉的兩個2,即13*2*2=52。
這個過程可以簡單地寫為:
(260,104)(/2/2) =>(65,26)=(39,26)=(13,26)=(13,13)=13. (*2*2) => 52 [1]

比較:

比較輾轉相除法與更相減損術的區別
(1)都是求最大公因數的方法,計算上輾轉相除法以除法為主,更相減損術以減法為主,計算次數上輾轉相除法計算次數相對較少,特別當兩個數字大小區別較大時計算次數的區別較明顯。
(2)從結果體現形式來看,輾轉相除法體現結果是以相除余數為0則得到,而更相減損術則以減數與差相等而得到

代碼實現

一:最簡單方法

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int m, n,temp,i;
    scanf("%d", &m);
    scanf("%d", &n);
    
    if (m>n)
    {
        temp = m;
        m = n;
        n = temp;
    }

    for (i = m; i >= 1;i--)
        if (m%i==0 && n%i==0)
            break;

    printf("%d\n", i);

    system("pause");
    return 0;
}

二:輾轉相除法(遞歸)

#include <stdio.h>
#include <stdlib.h>

int gcd(int a, int b) { int mod; if ((mod = a % b) == 0) return b; return gcd(b, mod); } int main()
{
    int m, n,ret;
    scanf("%d", &m);
    scanf("%d", &n);

    ret = gcd(m, n);
    printf("%d", ret);
    
    system("pause");
    return 0;
}

三:輾轉相除法(非遞歸)

int gcd(int a, int b)
{
    int mod=a % b;
    while (mod!=0)
    {
        a = b;
        b = mod;
        mod = a % b;
    }
    return b;
}

四:更相減損法(非遞歸)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int gcd(int a, int b)
{
    int val= a - b;
    while (val != b)
    {
        if (b>val)
        {
            a = b;
            b = val;
        }
        else
        {
            a = val;
        }
        val = a - b;
    }
    return val;
}

int main()
{
    int m, n,ret,temp,count=0;
    scanf("%d", &m);
    scanf("%d", &n);

    if (m == n)
    {
        printf("%d", m);
        return 0;
    }

    if (m < n)
    {
        temp = m;
        m = n;
        n = temp;
    }

    while (m%2 == 0 && n%2 == 0)
    {
        count++;
        m /= 2;
        n /= 2;
    }
    
    ret = gcd(m, n);
    printf("%d", ret*((int)pow(2,count)));  //使用pow需要進行(int)轉換,不然會報錯
    
    system("pause");
    return 0;
}

 

 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM