網(wǎng)站首頁 編程語言 正文
前言
兩個(gè)正整數(shù)的最大公約數(shù)(Greatest Common Divisor, GCD)是能夠整除這兩個(gè)整數(shù)的最大整數(shù)。兩個(gè)正整數(shù)的最大公約數(shù)的求法有多種解答,本文就三種方法做詳細(xì)介紹:窮舉法、歐幾里得算法(輾轉(zhuǎn)相除法)、遞歸方法。
我們從一道問題來引入:編寫計(jì)算最大公約數(shù)的函數(shù)Gcd(),在主函數(shù)中調(diào)用該函數(shù)計(jì)算并輸出從鍵盤任意輸入的最大公約數(shù)。
1.窮舉法
根據(jù)最大公約數(shù)的定義,我們可以采用一種最簡單的方法——窮舉法來編寫代碼。由于a和b的最大公約數(shù)不可能比a和b中的較小者還大,否則一定不能整除它,因此,先找到a和b中的較小者t,然后從t開始逐次減1嘗試每種可能,即檢驗(yàn)t到1之間的所有整數(shù),第一個(gè)滿足公約數(shù)條件的t,就是a和b的最大公約數(shù)。據(jù)此我們可編寫函數(shù)Gcd()如下:
//函數(shù)功能:計(jì)算a和b的最大公約數(shù),輸入負(fù)數(shù)時(shí)返回-1 int Gcd(int a, int b) { int i, t; if (a <=0 || b <= 0) return -1; t = a < b ? a : b; for (i=t; i>0; i--) { if (a%i==0 && b%i==0) return i; } return 1; }
這種方法簡單暴力,思維量小,但效率較低,且當(dāng)兩個(gè)正整數(shù)都較大,且最大公約數(shù)為1時(shí),循環(huán)的次數(shù)為較小數(shù)的值,可想而知所需時(shí)間會(huì)很長。
2.歐幾里得算法(輾轉(zhuǎn)相除法)
下面介紹一種求最大公約數(shù)較常用的辦法:歐幾里得算法(輾轉(zhuǎn)相除法)。
忽略數(shù)學(xué)原理,我們有如下算法:對(duì)正整數(shù)a和b,連續(xù)進(jìn)行求余運(yùn)算,直到余數(shù)為0為止,此時(shí)非0的除數(shù)就是最大公約數(shù)。設(shè) r=a mod b 表示a除以b的余數(shù),若 r≠0 ,則將b作為新的a,r作為新的b,重復(fù) a mod b 運(yùn)算,直到 r=0 為止,此時(shí)b為所求的最大公約數(shù)。例如,50和15的最大公約數(shù)的求解過程可表示為:Gcd(50, 15)=Gcd(15, 5)=Gcd(5, 0)=5。
用這種算法可編寫函數(shù)Gcd()如下:
//函數(shù)功能:計(jì)算a和b的最大公約數(shù),輸入負(fù)數(shù)時(shí)返回-1 int Gcd(int a, int b) { int r; if (a <= 0 || b <= 0) return -1; do{ r = a % b; a = b; b = r; } while (r != 0); return a; }
我們也可以考慮使用遞歸實(shí)現(xiàn)如下:
//函數(shù)功能:計(jì)算a和b的最大公約數(shù),輸入負(fù)數(shù)時(shí)返回-1 int Gcd(int a, int b) { if (a <= 0 || b <= 0) return -1; if (a % b == 0) return b; else return Gcd(b, a % b); }
3.遞歸方法
對(duì)于最大公約數(shù),還有3條性質(zhì):
性質(zhì)1 如果 a>b,則a和b與a-b和b的最大公約數(shù)相同;
性質(zhì)2 如果 b>a,則a和b與a和b-a的最大公約數(shù)相同;
性質(zhì)3 如果 a=b,則a和b的最大公約數(shù)與a值和b值相同。
對(duì)正整數(shù)a和b,當(dāng) a>b 時(shí),若a中含有與b相同的公約數(shù),則a中去掉b后剩余的部分a-b中也應(yīng)含有與b相同的公約數(shù),對(duì)a-b和b計(jì)算公約數(shù)就相當(dāng)于對(duì)a和b計(jì)算公約數(shù)。反復(fù)使用最大公約數(shù)的3條性質(zhì),直到a和b相等為止,這時(shí),a或b就是它們的最大公約數(shù)。
這就是所謂的第三種方法:遞歸方法。雖然此法被稱為遞歸方法,但只是思想方法運(yùn)用了遞歸的方法,并不代表只能使用遞歸實(shí)現(xiàn)。我們同樣可以通過非遞歸和遞歸兩種手段編寫函數(shù)Gcd()。非遞歸實(shí)現(xiàn)如下:
//函數(shù)功能:計(jì)算a和b的最大公約數(shù),輸入負(fù)數(shù)時(shí)返回-1 int Gcd(int a, int b) { if (a <= 0 || b <= 0) return -1; while (a != b) { if (a > b) a = a - b; else if (b > a) b = b - a; } return a; }
編寫遞歸函數(shù)如下:
//函數(shù)功能:計(jì)算a和b的最大公約數(shù),輸入負(fù)數(shù)時(shí)返回-1 int Gcd(int a, int b) { if (a <= 0 || b <= 0) return -1; if (a == b) return a; else if (a > b) return Gcd(a-b, b); else return Gcd(a, b-a); }
以上就是三種計(jì)算最大公約數(shù)的算法,可使用如下主函數(shù)來調(diào)用函數(shù)Gcd(),計(jì)算最大公約數(shù):
#include <stdio.h> int Gcd(int a, int b); int main(void) { int a, b, c; printf("Input a,b:"); scanf("%d,%d", &a, &b); c = Gcd(a,b); if (c != -1) printf("Greatest Common Divisor of %d and %d is %d\n", a, b, c); else printf("Input number should be positive!\n"); return 0; }
求兩個(gè)正整數(shù)的最大公約數(shù)的過程,實(shí)質(zhì)上是使用最大公約數(shù)的定義及性質(zhì)求解的過程,對(duì)此感興趣的伙伴們可以自己研究相關(guān)數(shù)學(xué)原理與證明。
附:相減法
這種方法比較易于理解,原理是先判斷兩個(gè)正整數(shù)大小,并將較大數(shù)與較小數(shù)的差值賦給較大數(shù),循環(huán)此步驟直到兩數(shù)相等,此時(shí)得出最大公約數(shù)。
代碼如下:
#include<stdio.h> int main() { int m,n; printf("請(qǐng)輸入兩個(gè)正整數(shù):"); scanf("%d %d",&m,&n); printf("%d%和%d的最大公約數(shù)是",m,n); while(m!=n) { if(m>n) { m=m-n; }else { n=n-m; } } printf("%d",n); return 0; }
參考文獻(xiàn):
蘇小紅 王甜甜 趙玲玲 范江波 車萬翔 等編著 王宇穎 主審,C語言程序設(shè)計(jì)學(xué)習(xí)指導(dǎo)(第4版),高等教育出版社,P57-60.
總結(jié)
原文鏈接:https://blog.csdn.net/weixin_60921752/article/details/121846028
相關(guān)推薦
- 2022-10-04 C語言指針和數(shù)組深入探究使用方法_C 語言
- 2022-04-24 詳解golang?定時(shí)任務(wù)time.Sleep和time.Tick實(shí)現(xiàn)結(jié)果比較_Golang
- 2022-04-19 C#使用CancellationTokenSource?取消?Task的方法_C#教程
- 2022-04-14 Python中的flask框架詳解_python
- 2022-03-29 在pyqt5中展示pyecharts生成的圖像問題_python
- 2022-05-11 C++程序代碼優(yōu)化的方法實(shí)例大全_C 語言
- 2021-12-10 k8s部署ingress-nginx的方法步驟_nginx
- 2022-03-21 詳解c++優(yōu)先隊(duì)列priority_queue的用法_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支