求最大公约数的4种常用算法

您所在的位置:网站首页 最大公约数和最小公倍数的题目 求最大公约数的4种常用算法

求最大公约数的4种常用算法

2023-12-23 21:02| 来源: 网络整理| 查看: 265

一、问题描述: 运行最大公约数的常用算法

二、问题分析与设计: 1.辗转相除法(又名欧几里德法)

①函数嵌套调用

其算法过程为: 前提:设两数为a,b设其中a 做被除数,b做除数,temp为余数 1、大数放a中、小数放b中; 2、求a/b的余数; 3、若temp=0则b为最大公约数; 4、如果temp!=0则把b的值给a、temp的值给a; 5、返回第二步;

代码:

#include using namespace std; int divisor(int a,int b) //自定义函数求最大公约数 { int temp; //整形零时变量 if(a temp=a%b; //a中大数除以b中小数循环取余,直到b及余数为0 a=b; b=temp; } return a; //返回最大公约数到调用函数处 } int multipile(int a,int b) //自定义函数求最小公倍数 { int divisor(int a,int b); //自定义函数返回值类型 int temp; temp=divisor(a,b); //再次调用自定义函数,求出最大公约数 return(a*b/temp); //返回最小公倍数到主调函数处进行输出 } int main() { int m,n,t1,t2; printf("请输入两个整形数字:"); scanf("%d%d",&m,&n); if(m0) { printf("请重新输入正确整数:"); cin.clear(); //清除错误标记,重新打开输入流 cin.sync (); scanf("%d%d",&m,&n); } t1=divisor(m,n); t2=multipile(m,n); printf("最大公因数为:%d\n",t1); printf("最小公倍数为:%d\n",t2); return 0; }

测试及测试代码与平均运行时间: 测试代码:

#include #include #include int divisor(int a,int b) { int temp; if(a temp=a%b; a=b; b=temp; } return a; } void main() { int m[5000],n[5000],t1,i; clock_t start,finish; double duration; time_t t=time(NULL); srand(t); for(i=0;i t1=divisor(m[i],n[i]); printf("%d %d %d\n",m[i],n[i],t1); } finish=clock(); duration=(double)(finish-start)/5000; //平均运行时间 printf("%f milliseconds\n",duration); }

②函数递归调用

#include #include using namespace std; int gcd(int a,int b) //自定义函数求最大公约数 { if(a%b==0) //终止条件 return b; //b及为最大公约数 else return gcd(b,a%b); } int main() { int m,n,t1; printf("请输入两个整形数字:"); scanf("%d%d",&m,&n); if(m0) //判断输入两数字是否小于零或为小数 { printf("请重新输入正确整数:"); cin.clear(); //清除错误标记,重新打开输入流 cin.sync (); scanf("%d%d",&m,&n); } t1=gcd(m,n); printf("最大公因数为:%d\n",t1); printf("最小公倍数为:%d\n",m*n/t1); return 0; }

测试及测试代码与平均运行时间: 测试代码:

#include #include #include int gcd(int a,int b) { if(a%b==0) return b; else return gcd(b,a%b); } void main() { int m[2000],n[2000],t1,i; clock_t start,finish; double duration; time_t t=time(NULL); srand(t); for(i=0;i t1=gcd(m[2000],n[2000]); printf("%d %d %d %d\n",m[i],n[i],t1); } finish=clock(); duration=(double)(finish-start)/2000; //平均运行时间 printf("%f seconds\n",duration); }

流程图 在这里插入图片描述 2.穷举法(也称枚举法)利用数学定义

穷举法求两个正整数的最大公约数的解题步骤:从两个数中较小数开始由大到小列举,直到找到公约数立即中断列举,得到的公约数便是最大公约数。

定义1:对两个正整数a,b如果能在区间[a,0]或[b,0]内能找到一个整数temp能同时被a和b所整除,则temp即为最大公约数。 定义2:对两个正整数a,b,如果若干个a之和或b之和能被b所整除或能被a所整除,则该和数即为所求的最小公倍数。 代码:

#include using namespace std; int divisor(int a,int b) //自定义函数求两数的最大公约数 { int temp; temp=(a>b)?b:a; //采用条件运算表达式求出两个数中的最小值 while(temp>0) { if(a%temp==0&&b%temp==0) //只要找到一个数能同时被a,b所整除,则中止循环 break; temp--; //如不满足if条件则变量自减,直到能被a,b所整除 } return(temp); //返回满足条件的数到主调函数处 } int multiple(int a,int b) { int p,q,temp; p=(a>b)?a:b; //求两个数中的最大值 q=(a>b)?b:a; //求两个数中的最小值 temp=p; //最大值赋给p为变量自增作准备 while(1) //利用循环语句来求满足条件的数值 { if(p%q==0) break; //只要找到变量的和数能被a或b所整除,则中止循环 p+=temp; //如果条件不满足则变量自身相加 } return(p); } int main() { int m,n,t1,t2; printf("请输入两个整形数字:"); scanf("%d%d",&m,&n); if(m0) { printf("请重新输入正确整数:"); cin.clear(); //清除错误标记,重新打开输入流 cin.sync (); scanf("%d%d",&m,&n); } t1=divisor(m,n); t2=multiple(m,n); printf("最大公因数为:%d\n",t1); printf("最小公倍数为:%d\n",t2); return 0; }

测试及测试代码与平均运行时间: 测试代码:

#include #include #include int divisor(int a,int b) { int temp; temp=(a>b)?b:a; while(temp>0) { if(a%temp==0&&b%temp==0) break; temp--; } return(temp); } void main() { int m[5000],n[5000],t1,i; clock_t start,finish; double duration; time_t t=time(NULL); srand(t); for(i=0;i t1=divisor(m[i],n[i]); printf("%d %d %d\n",m[i],n[i],t1); } finish=clock(); duration=(double)(finish-start)/5000; //平均运行时间 printf("%f seconds\n",duration); }

流程图 在这里插入图片描述 3. 更相减损法

更相减损术,是出自《九章算术》的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合。《九章算术》是中国古代的数学专著,其中的“更相减损术”可以用来求两个数的最大公约数,即“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。” 翻译成现代语言如下: 第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。 第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。 则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。 其中所说的“等数”,就是最大公约数。求“等数”的办法是“更相减损”法。所以更相减损法>也叫等值算法。

代码:

#include #include using namespace std; int gcd(int m,int n) //求最大公约数 { int i=0,temp,x; while(m%2==0 && n%2==0) //判断m和n能被多少个2整除(i个) { m/=2; n/=2; i+=1; } if(m x=m-n; //{ 以较大的数减较小的数, m=(n>x)?n:x; n=(n printf("请重新输入正确整数:"); cin.clear(); //清除错误标记,重新打开输入流 cin.sync (); scanf("%d%d",&m,&n); } t1=gcd(m,n); printf("最大公因数为:%d\n",t1); printf("最小公倍数为:%d\n",m*n/t1); return 0; }

测试及测试代码与平均运行时间: 测试代码:

#include #include #include #include int gcd(int m,int n) //求最大公约数 { int i=0,temp,x; while(m%2==0 && n%2==0) //判断m和n能被多少个2整除(i个) { m/=2; n/=2; i+=1; } if(m x=m-n; //{以较大的数减较小的数, m=(n>x)?n:x; n=(n m[i]=rand()%100; n[i]=rand()%100; } start=clock(); for(i=0;i int factor = 0; //返回最大公约数x和y int temp; if ( x return 0; } while ( x != y ) { //当x时偶数时 if ( x & 0x1 ) { if ( y & 0x1 ) { //当x和y都是偶数时 y = ( x - y ) >> 1; x -= y; } else { //当x是偶数,y是奇数 y >>= 1; } } else { //当x是奇数 if ( y & 0x1 ) { x >>= 1; if ( x //当x和y都是奇数 x >>= 1; y >>= 1; ++factor; } } } return ( x printf("请重新输入正确整数:"); cin.clear(); //清除错误标记,重新打开输入流 cin.sync (); scanf("%d%d",&m,&n); } t1=Stein(m,n); printf("最大公因数为:%d\n",t1); return 0; }

测试及测试代码与平均运行时间: 测试代码:

#include #include #include int Stein( unsigned int x, unsigned int y ) /* return the greatest common divisor of x and y */ { int factor = 0; int temp; if ( x return 0; } while ( x != y ) { if ( x & 0x1 ) {/* when x is odd */ if ( y & 0x1 ) {/* when x and y are both odd */ y = ( x - y ) >> 1; x -= y; } else {/* when x is odd and y is even */ y >>= 1; } } else {/* when x is even */ if ( y & 0x1 ) {/* when x is even and y is odd */ x >>= 1; if ( x /* when x and y are both even */ x >>= 1; y >>= 1; ++factor; } } } return ( x m[i]=rand()%100; n[i]=rand()%100; } start=clock(); for(i=0;i if (u == 0) return v; if (v == 0) return u; // 寻找两个数的最大公约数 if (~u & 1) // u是偶数 { if (v & 1) // v是奇数 return gcd(u >> 1, v); else // u和v都是偶数 return gcd(u >> 1, v >> 1) 1); // 减少较大的变量 if (u > v) return gcd((u - v) >> 1, v); return gcd((v - u) >> 1, u); } int main() { int m,n,t1; printf("请输入两个整形数字:"); scanf("%d%d",&m,&n); if(m0) //判断输入两数字是否小于零或为小数 { printf("请重新输入正确整数:"); cin.clear(); //清除错误标记,重新打开输入流 cin.sync (); scanf("%d%d",&m,&n); } t1=gcd(m,n); printf("最大公因数为:%d\n",t1); return 0; }

测试及测试代码与平均运行时间: 测试代码:

#include #include #include int gcd(int u,int v) { if (u == 0) return v; if (v == 0) return u; if (~u & 1) { if (v & 1) return gcd(u >> 1, v); else return gcd(u >> 1, v >> 1) 1); if (u > v) return gcd((u - v) >> 1, v); return gcd((v - u) >> 1, u); } void main() { int m[5000],n[5000],t1,i; clock_t start,finish; double duration; time_t t=time(NULL); srand(t); for(i=0;i t1=gcd(m[i],n[i]); printf("%d %d %d\n",m[i],n[i],t1); } finish=clock(); duration=(double)(finish-start)/5000; //平均运行时间 printf("%f seconds\n",duration); }

流程图: 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3