1、辗转相除法:
两个整数的最大公约数是能够同时整除它们的最大的正整数。辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约数。
如:319,377
a b a%b
377%319=58
319%58=29
58%29=0
所以最后结果为29。
递归和非递归代码如下:
#include<iostream>
#include<cstring>
using namespace std;
int gcd(int a,int b)//递归
{
int tmp=a%b;
if(tmp==0)
return b;
else
return gcd(b,tmp);
}
int gcd1(int a,int b)//非递归
{
int tmp;
while(b)
{
tmp=a%b;
a=b;
b=tmp;
}
return a;
}
int swap(int &a,int &b)
{
int tmp=a;a=b;b=tmp;
}
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a<b)
swap(a,b);
printf("(%d,%d)\n",gcd(a,b),gcd1(a,b));
}
return 0;
}
2.更相减损法:
1、如果两个数都是偶数,则都除以2,记下除以2的次数。直到不都是偶数,执行下一步。
2、以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
如:30、42
a b a-b
30 42
15 21 /2
21—15 =6
15— 6 =9
9 — 6 =3
6 — 3 =3
结果为 3*(1<<1)=6
我用了一次用递归方法超内存,就没有再用了。
非递归代码如下:
#include<iostream>
#include<cstring>
using namespace std;
int gcd(int a,int b)//非递归
{
while(a!=b)
{
if(a>b)
a-=b;
else
b-=a;
}
return b;
}
int swap(int &a,int &b)
{
int tmp=a;a=b;b=tmp;
}
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
{
int cnt=0;
while(a%2==0&&b%2==0)
{
a>>=1;
b>>=1;
cnt++;
}
printf("%d\n",gcd(a,b)<<cnt);
}
return 0;
}