【筆記|C++】最大公約數(shù)、最小公倍數(shù)的四種求法

前言

Hello峭跳!小伙伴!

非常感謝您閱讀海轟的文章缺前,倘若文中有錯誤的地方蛀醉,歡迎您指出~

?

自我介紹 ?(?ˊ?ˋ)?

昵稱:海轟

標(biāo)簽:程序猿|C++選手|學(xué)生

簡介:因C語言結(jié)識編程,隨后轉(zhuǎn)入計(jì)算機(jī)專業(yè)衅码,有幸拿過國獎拯刁、省獎等,已保研逝段。目前正在學(xué)習(xí)C++/Linux(真的真的太難了~)

學(xué)習(xí)經(jīng)驗(yàn):扎實(shí)基礎(chǔ) + 多做筆記 + 多敲代碼 + 多思考 + 學(xué)好英語垛玻!

?
<font color="red" font-wight="800">【動畫消消樂】</font> 平時學(xué)習(xí)生活比較枯燥,無意之間對一些網(wǎng)頁奶躯、應(yīng)用程序的過渡/加載動畫產(chǎn)生了濃厚的興趣帚桩,想知道具體是如何實(shí)現(xiàn)的? 便在空閑的時候?qū)W習(xí)下如何使用css實(shí)現(xiàn)一些簡單的動畫效果巫糙,文章僅供作為自己的學(xué)習(xí)筆記朗儒,記錄學(xué)習(xí)生活,爭取理解動畫的原理参淹,多多“消滅”動畫醉锄!

概念

最大公約數(shù):也稱最大公因數(shù)、最大公因子浙值,指兩個或多個整數(shù)共有約數(shù)中最大的一個
最小公倍數(shù):兩個或多個整數(shù)公有的倍數(shù)叫做它們的公倍數(shù)恳不,其中除0以外最小的一個公倍數(shù)就叫做這幾個整數(shù)的最小公倍數(shù)。

求法

注:以求兩個正整數(shù)的最大公因數(shù)為例

方法一【枚舉法】

思路:

  • 找到a开呐、b中的較小值
  • 從該值開始烟勋,判斷該數(shù)能否同時被a规求、b整除
  • 若可以被整除 返回該值
  • 若不可以 則遞減1
#include <iostream>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    int temp = a > b ? b : a;
    while (temp)
    {
        if (a % temp == 0 && b % temp == 0)
        {
            break;
        }
        --temp;
    }
    return temp;
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

方法二【輾轉(zhuǎn)相除法】

輾轉(zhuǎn)相除法是利用以下性質(zhì)來確定兩個正整數(shù) a 和 b 的最大公因子的:

  • 若 r 是 a ÷ b 的余數(shù),且r不為0卵惦, 則gcd(a,b) = gcd(b,r)

注:gcd表示最大公因數(shù)阻肿,gcd(a,b)表示a、b兩數(shù)的最大公因數(shù)

程序設(shè)計(jì)思路是:

  1. 令r為a/b所得余數(shù)(0<=r)
  2. 若 r= 0沮尿,算法結(jié)束丛塌;b 即為答案。
  3. 互換:置 a←b畜疾,b←r赴邻,并返回第一步。
#include <iostream>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    int r;
    // 當(dāng)a不能被b整除完全時
    // 令a=b b=a%b
    // 重復(fù)循壞 直到a%b==0
    // 返回b b就是最大公因數(shù)
    while (a % b != 0)
    {
        r = a % b;
        a = b;
        b = r;
    }
    return b;
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

同樣的思路啡捶,使用遞歸實(shí)現(xiàn):

核心:

  • 若 r 是 a ÷ b 的余數(shù)姥敛,且r不為0, 則gcd(a,b) = gcd(b,r)
#include <iostream>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    if (a % b == 0)
    {
        return b;
    }
    else
    {
        return gcd(b, a % b);
    }
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

方法三【更相減損法】

程序設(shè)計(jì)步驟:

  • 第一步:任意給定兩個正整數(shù)瞎暑;判斷它們是否都是偶數(shù)彤敛。若是,則用2約簡金顿;若不是則執(zhí)行第二步臊泌。
  • 第二步:以較大的數(shù)減較小的數(shù),接著把所得的差與較小的數(shù)比較揍拆,并以大數(shù)減小數(shù)渠概。繼續(xù)這個操作,直到所得的減數(shù)和差相等為止嫂拴。
  • 則第一步中約掉的若干個2的積與第二步中等數(shù)的乘積就是所求的最大公約數(shù)播揪。
#include <iostream>
#include <math.h>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    // 判斷兩數(shù)是否都是偶數(shù)
    // 若都是 則都除以2
    // 直到其中一個數(shù)為奇數(shù)
    int count = 0;// 記錄2的個數(shù)
    while (a % 2 == 0 && b % 2 == 0)
    {
        a /= 2;
        b /= 2;
        ++count;
    }
    // 當(dāng)a!=b時
    // 用a、b中的較大數(shù)減去較小數(shù)字
    // 一直循環(huán) 直到a==b
    while (a != b)
    {
        if (a > b)
        {
            a -= b;
        }
        else
        {
            b -= a;
        }
    }
    // 注意需要乘以count個2
    return a * pow(2, count);
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

遞歸:

#include <iostream>
#include <math.h>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    // 在這里遞歸時 沒有對a b進(jìn)行同時約2的操作
    if (a == b)
    {
        return a;
    }
    else if (a > b)
    {
        a -= b;
    }
    else
    {
        b -= a;
    }
    return gcd(a, b);
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

方法四【Stein算法】

用Cn表示最大公因數(shù)

算法步驟:

1筒狠、設(shè)置An=|A|猪狈、Bn=|B|、Cn=1和n=1

2辩恼、如果An=Bn,那么An(或Bn)*Cn是最大公約數(shù),算法結(jié)束

3雇庙、如果An=0,Bn是最大公約數(shù)灶伊,算法結(jié)束

4疆前、如果Bn=0,An是最大公約數(shù)聘萨,
算法結(jié)束

5竹椒、如果An和Bn都是偶數(shù),則An+1=An/2米辐,Bn+1=Bn/2胸完,Cn+1=Cn*2(注意书释,乘2只要把整數(shù)左移一位即
可,除2只要把整數(shù)右移一位即可)

6赊窥、如果An是偶數(shù)爆惧,Bn不是偶數(shù),則An+1=An/2锨能,Bn+1=Bn检激,Cn+1=Cn(很顯然啦,2不是奇數(shù)的約數(shù))

7腹侣、如果Bn是偶數(shù),An不是偶數(shù)齿穗,則Bn+1=Bn/2傲隶,An+1=An,Cn+1=Cn(很顯然啦窃页,2不是奇數(shù)的約數(shù))

8跺株、如果An和Bn都不是偶數(shù),則An+1=|An-Bn|/2(或An+1=|An-Bn|也行)脖卖,Bn+1=min(An,Bn)乒省,Cn+1=Cn

9、n=n+1畦木,轉(zhuǎn)2

非遞歸:

#include <iostream>
#include <math.h>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    int count = 0;
    if (a == b)
        return a;
    if (a == 0)
        return b;
    if (b == 0)
        return a;
    while (a != b)
    {
        // a&1==1 說明a是奇數(shù) 與a%2==1得到的效果一樣
        // 都是判斷a是奇數(shù)還是偶數(shù)
        if (a & 1)
        {
            if (b & 1)
            {
                //a,b都是奇數(shù)時
                // 提前存儲a 因?yàn)楹竺鎍變了
                int temp = a;
                a = abs(a - b) >> 1;
                b = min(temp, b);
            }
            else
            {
                //a是奇數(shù) b是偶數(shù)
                b >>= 1;
            }
        }
        else
        {
            if (b & 1)
            {
                //a是偶數(shù) b是奇數(shù)
                a >>= 1;
            }
            else
            {
                //a袖扛、b都是偶數(shù)
                a >>= 1;
                b >>= 1;
                ++count;
            }
        }
    }
    return a << count;
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

遞歸實(shí)現(xiàn):

#include <iostream>
#include <math.h>
using namespace std;
// 求最大公約數(shù)
int gcd(int a, int b)
{
    // 如果A=0 B是最大公因數(shù) 返回B
    if (a == 0)
        return b;
    
    // 如果B=0 A是最大公因數(shù) 返回A
    if (b == 0)
        return a;
    
    // 如果A、B都是偶數(shù)
    // 則分別除以因子2
    // 直到不滿足二者同時為偶數(shù)
    if (a % 2 == 0 && b % 2 == 0)
        return 2 * gcd(a >> 1, b >> 1);
    
    // 若a是偶數(shù) b不是偶數(shù)
    // 說明因子2不在公共因子中 可以直接除去2
    else if (a % 2 == 0)
        return gcd(a >> 1, b);
    
    // 若b是偶數(shù) a不是偶數(shù)
    // 說明因子2不在公共因子中 可以直接除去2
    else if (b % 2 == 0)
        return gcd(a, b >> 1);
    
    // 若 a十籍、b都是奇數(shù)時
    // An+1 =|An -Bn|蛆封,Bn+1 =min(An,Bn)
    else
        // abs(a-b)/2也對
        // return gcd(abs(a - b)/2, min(a, b));
        return gcd(abs(a - b), min(a, b));
}
int main()
{
    int a, b;
    cin >> a >> b;
    cout << "gcd(a,b)=" << gcd(a, b) << endl;
    return 0;
}

最小公倍數(shù)求法就比較簡單了,求出最大公因數(shù)后勾栗,之間用a*b/gcd(a,b)即可

結(jié)語

文章僅作為學(xué)習(xí)筆記惨篱,記錄從0到1的一個過程

希望對您有所幫助,如有錯誤歡迎小伙伴指正~

在這里插入圖片描述
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末围俘,一起剝皮案震驚了整個濱河市砸讳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌界牡,老刑警劉巖簿寂,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異欢揖,居然都是意外死亡陶耍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門她混,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烈钞,“玉大人泊碑,你說我怎么就攤上這事√盒溃” “怎么了馒过?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長酗钞。 經(jīng)常有香客問我腹忽,道長,這世上最難降的妖魔是什么砚作? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任窘奏,我火速辦了婚禮,結(jié)果婚禮上葫录,老公的妹妹穿的比我還像新娘着裹。我一直安慰自己,他們只是感情好米同,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布骇扇。 她就那樣靜靜地躺著,像睡著了一般面粮。 火紅的嫁衣襯著肌膚如雪少孝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天熬苍,我揣著相機(jī)與錄音稍走,去河邊找鬼。 笑死冷溃,一個胖子當(dāng)著我的面吹牛钱磅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播似枕,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼盖淡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凿歼?” 一聲冷哼從身側(cè)響起褪迟,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎答憔,沒想到半個月后味赃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虐拓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年心俗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡城榛,死狀恐怖揪利,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情狠持,我是刑警寧澤疟位,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站喘垂,受9級特大地震影響甜刻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜正勒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一得院、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧章贞,春花似錦尿招、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怪蔑。三九已至里覆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缆瓣,已是汗流浹背喧枷。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弓坞,地道東北人隧甚。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像渡冻,于是被迫代替她去往敵國和親戚扳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容