C/C++ 求两个数的最大公约数

求两个数的最大公约数
最大公约数的英文是Greatest Common Divisor,简称GCD。程序里面用gcd表示。

方法一:从定义出发最直接法
从两个数中比较大的数开始计算,找不到就减小1。比如36和12两个数,就从36开始,36不是最大公约数,然后35也不是,34也不是,33也不是。一直到,14也不是,13也不是,最后到12,所以12就是最大公约数。
比如12和8。就从12开始,12不是最大公约数,然后11也不是,10也不是,一直到8也不是,7也不是,一直到4停止。4就是最大公约数。

#include <iostream>
using namespace std;

int main() {
   int a,b,gcd;
   cin>>a>>b;
   gcd=a>b?a:b;
   while(a%gcd!=0||b%gcd!=0)
       gcd--;
   cout<<"最大公约数为:"<<gcd<<endl;

   return 0;
}

gcd=a>b?a:b; 这一行的意思是如果a>b成立,就把a赋值给gcd,如果不成立,就把b赋值给gcd。也就是说,把两个数中比较大的值给gcd。
另外,最大公约数的求法,是“找到一个能被两个数同时整除的最大的数”。用while来执行的话,就应该是,while的循环应该是在“当找不到能被两个数同时整除的数的时候,一直执行下去”。
但是要用while来表示就比较麻烦了。while的括号里的条件应该是“a能被gcd整除而且同时b也能被gcd整除”的补集,即“a整除gcd不为零或者b整除gcd不为零”。只要“a整除gcd不为零或者b整除gcd不为零”,while就一直执行,直到找到一个gcd,能够同时被a和b整除,while才中断。
这个比较理解起来比较拗口。

执行结果:

8 12
最大公约数为:4

有的人说,为什么要从大的数开始,从比较小的数开始计算不是更好吗?可以。那么程序的gcd赋值这一行,改成gcd=a>b?b:a;
程序改成:

#include <iostream>
using namespace std;

int main() {
   int a,b,gcd;
   cin>>a>>b;
   gcd=a>b?b:a;//把较小的值给gcd
   while(a%gcd!=0||b%gcd!=0)
       gcd--;
   cout<<"最大公约数为:"<<gcd<<endl;

   return 0;
}

其他都不变。执行结果:

88 35
最大公约数为:1

方法二:辗转相除法
首先大家需要知道什么是辗转相除法。具体内容可以百度。这里简单介绍一下:
如果两个数,分别是15和49。首先用
49除以15,余数是4,
然后用15除以4,余数是3,
然后用4除以3,余数是1,
然后用3除以1,余数是0。此时的除数1就是两个数的最大公约数。
如果两个数,分别是14和49。首先用
49除以14,余数是7,
然后用14除以7,余数是0。此时的除数7就是两个数的最大公约数。
程序的算法应该是:
首先让比较大的那个数除以小的数,余数赋值给tmp。如果此时余数为0,那么小的数就是最大公约数。如果余数不为零,那么让刚才的除数成为被除数,而把tmp的值改成除数,再除一次,如果余数为零,就停止循环,如果余数还是不为零,就继续这个循环,知道余数为零为止。
这里需要把赋值传递。tmp的值给b,成为除数,b的值给a,成为被除数。

#include <iostream>
using namespace std;

int main() {
   int a,b,tmp;
   cin>>a>>b;
   while(tmp=a%b)
   {
       a=b;
       b=tmp;
   }
   cout<<"最大公约数为:"<<b<<endl;

   return 0;
}

而且这个程序用了一个巧妙的办法,不需要一上来就比较两个数的大小。while括号中,把a%b的结果给了tmp。如果a比b大,那很好理解。如果a比b小呢,此时tmp不为零,执行while语句时,马上就把b的值给了a。比如a是12,b是36。12除以36,余数仍然是12。while括号中的值不为零,执行while语句。把36给了a,而把tmp(此时tmp=12)给了b,等于是a和b互换了一下,然后再次执行while循环:先判断while括号中的值,而此时tmp=36%12而等于0,while立刻停止执行。最大公约数就是b。

执行结果如下:

36 12
最大公约数为:12
12 36
最大公约数为:12

你可能感兴趣的:(c++,c语言)