这是我算法学习标签下的第一篇随笔,首先我想声明,在看了很多博客后,我的想法就是,尽量不去盲目复制别人的东西,一个原因是盲目复制不一定能发现其文章中的错误,二是可以加深自己的理解程度,并且将博客写得通俗易懂,转载别人的东西一定要注明出处。还有我的一个习惯就是,把东西写短一点,所以有可能会将一个本来应在一篇文章的东西,写成好几节。
Euclid Algorithm 又称辗转相除法,用途是求两个正整数a,b的最大公约数,gcd(a,b )表示a和b的最大公约数(gcd = greatest common divisor)。
内容:gcd(a,b)=gcd(b,a%b);
条件:a,b>0(当a%b=0时,使用该公式后就不能再使用)
关于最大公约数:前提是对于两个正整数而言,约数也必须是正整数。不会讨论 -4 8、4 0 等类似数的最大公约数,可以说是-4和8没有最大公约数,4和0也没有最大公约数。虽然对于次算法运行起来这两个是有结果的,-4和4。
证明:
将a表示为 a=kb+r,则 r=a%b , r=a-kb;
假设d为a,b的一个公约数,则a%d = 0 , b%d = 0 , 又r = a - kb,所以r % d = 0;
整理下:b % d = 0 , r % d = 0( (a % b) % d = 0 )
即 d也是b和a%b的公约数,所以a和b的最大公约数也是b和a%b的最大公约数。
递归形式代码:
#include<iostream> using namespace std; int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } int main() { int a,b; cout<<"Please enter two integers:"<<endl; cin>>a>>b; cout<<a<<" and "<<b<<"‘s gcd is:"<<endl; cout<<gcd(a,b)<<endl; return 0; }
非递归形式:
#include<iostream> using namespace std; int gcd(int a,int b) { int temp; while(b!=0) { temp=b; b=a%b; a=temp; } return a; } int main() { int a,b; cout<<"Please enter two integers:"<<endl; cin>>a>>b; cout<<a<<" and "<<b<<"‘s gcd is:"<<endl; cout<<gcd(a,b)<<endl; return 0; }
运行截图:
有两点想说明的是:
1.出现类似gcd(4,0) 的含义并不是直接代表gcd(4,0)=4,因为4和0的公约数不存在。而是由前面的,得到了gcd(4,0),某个数mod 4 = 0,即有个数被4整除了,所以最大公约数是4。
2.网上有很多代码先判断了a与b的大小,a<b时候,要交换a与b的值。其实当a<b的时候,temp=b; b=a%b; a=temp; 就是一个swap的过程,所以交换位置是没有必要的。求gcd(4,8)=gcd(8,4)=...。
时间: 2024-10-11 08:31:53