c++,使用欧几里得算法计算两个数的最大公约数,分别用递推和递归两种算法实现5

合集下载

求最大公约数(GCD)的两种算法

求最大公约数(GCD)的两种算法

求最⼤公约数(GCD)的两种算法之前⼀直只知道欧⼏⾥得辗转相除法,今天学习了⼀下另外⼀种、在处理⼤数时更优秀的算法——Stein特此记载1.欧⼏⾥得(Euclid)算法⼜称辗转相除法,依据定理gcd(a,b)=gcd(b,a%b)实现过程演⽰: sample:gcd(15,10)=gcd(10,5)=gcd(5,0)=5C语⾔实现:1int Euclid_GCD(int a, int b)2 {3return b?Euclid_GCD(b, a%b):a;4 }2.Stein 算法⼀般实际应⽤中的整数很少会超过64位(当然现在已经允许128位了),对于这样的整数,计算两个数之间的模是很简单的。

对于字长为32位的平台,计算两个不超过32位的整数的模,只需要⼀个指令周期,⽽计算64位以下的整数模,也不过⼏个周期⽽已。

但是对于更⼤的素数,这样的计算过程就不得不由⽤户来设计,为了计算两个超过 64位的整数的模,⽤户也许不得不采⽤类似于多位数除法⼿算过程中的试商法,这个过程不但复杂,⽽且消耗了很多CPU时间。

对于现代密码算法,要求计算 128位以上的素数的情况⽐⽐皆是,设计这样的程序迫切希望能够抛弃除法和取模。

依据定理:gcd(a,a)=a,也就是⼀个数和其⾃⾝的公约数仍是其⾃⾝。

gcd(ka,kb)=k*gcd(a,b),也就是运算和倍乘运算可以交换。

特殊地,当k=2时,说明两个偶数的必然能被2整除。

当k与b互为质数,gcd(ka,b)=gcd(a,b),也就是约掉两个数中只有其中⼀个含有的因⼦不影响。

特殊地,当k=2时,说明计算⼀个偶数和⼀个奇数的时,可以先将偶数除以2。

C语⾔实现:1int Stein_GCD(int x, int y)2 {3if (x == 0) return y;4if (y == 0) return x;5if (x % 2 == 0 && y % 2 == 0)6return2 * Stein_GCD(x >> 1, y >> 1);7else if (x % 2 == 0)8return Stein_GCD(x >> 1, y);9else if (y % 2 == 0)10return Stein_GCD(x, y >> 1);11else12return Stein_GCD(min(x, y), fabs(x - y));13 }。

关于C语言求两个数的最大公约数

关于C语言求两个数的最大公约数

关于C语⾔求两个数的最⼤公约数
⼀、求两个数的最⼤公约数有两种⽅法
1、求差法
对于传⼊的两个数,⽤较⼤的数减去较⼩的数,然后拿差与较⼩的数相⽐,若是相等,则这个数就是最⼤公约数。

否则,对于差和较⼩的数再次重复上述的过程。

关于算法,则可利⽤while的循环来重复或者利⽤递归算法,这⾥采⽤递归来求解
1int division(int n,int m)
2 {
3if(n<m)
4 division(m,n); //交换n,m的值
5else if(n==m)
6return n;
7else
8 {
9int temp=n;
10 n=m;
11 m=temp-n;
12 division(n,m); //重复上述过程
13 }
14 }
2、求模法
求模法就是对于传⼊的两个数,⽤较⼤的数来对较⼩的数求模,要是模为零,则较⼤的数则为最⼤公约数。

若是模不为零,则对于较⼩的数和模继续上述的过程。

此过程与上述的求差法⼏乎⼀模⼀样,仍利⽤递归法.
1int division(int n,int m)
2 {
3if(n<m)
4 division(m,n); //交换m与n
5else if(m==0)
6return n;
7else
8 {
9int temp=n;
10 n=m;
11 m=temp%n;
12 division(n,m); //重复上述过程
13 }
14 }
对于最⼩公倍数,则是两数相乘,然后除以最⼤公约数。

求两个整数m,n的最大公约数的欧几里德算法

求两个整数m,n的最大公约数的欧几里德算法

求两个整数m,n的最大公约数的欧几里德算法
欧几里德算法,也称辗转相除法,是一种求两个数的最大公约数的算法。

方法如下:设a和b是两个不全为0的整数,求它们的最大公约数。

不妨设a > b,用a除以b,得到余数r,将b除以r,得到余数r1,将r除以r1,得到余数r2,如此继续进行,每次将所得的商作为除数,余数作为被除数,直到余数为0为止,此时所得的被除数即为a和b的最大公约数。

可以通过递归来实现欧几里德算法。

例如,假设有两个整数m和n,我们可以使用如下Python代码来实现欧几里德算法:
def gcd(m, n):
if n == 0:
return m
else:
return gcd(n, m % n)
在这个函数中,如果n等于0,则返回m,否则通过递归调用gcd(n, m % n)来继续求解。

这个算法的正确性可以通过数学归纳法来证明。

首先,当n等于0时,gcd(m, n)等于m,显然成立。

接下来,假设gcd(n, m % n)等于d,则gcd(m, n)等于gcd(n, m % n)等于d,也就是说,d是m和n的公因数。

另一方面,如果x是m和n的公因数,则它也是n和m % n的公因数。

因此,d是m和n的最大公因数。

欧几里德算法的时间复杂度为O(log(max(m, n))),因为每一次递归都能将一个参数减半。

因此,这个算法在实践中是非常高效的。

总之,欧几里德算法是求两个数的最大公约数的一种简单而优美的方法,递归实现更容易理解和实现,且在时间复杂度上表现出色,因此在实际应用中被广泛使用。

使用递归求两个数字的最大公约数.

使用递归求两个数字的最大公约数.

使用递归求两个数字的最大公约数.文章主题:使用递归求两个数字的最大公约数在数学中,最大公约数(Greatest Common Divisor,简称GCD)指的是能整除两个或多个整数的最大正整数。

求最大公约数的方法多种多样,其中使用递归是一种常见且优雅的方式。

通过递归,我们可以简洁地表达求解最大公约数的过程,使得代码更加优雅和易读。

下面我们将以递归的方式来讨论如何求两个数字的最大公约数,并深入探讨递归的原理和应用。

一、递归的基本原理及应用递归,顾名思义,就是函数自己调用自己的过程。

在数学和计算机科学中,递归通常用于解决可以被分解为相似子问题的问题。

通过递归调用,我们可以简洁地解决复杂的问题,如斐波那契数列的求解、二叉树的遍历等。

在求两个数字的最大公约数时,我们也可以利用递归的思想,将问题不断分解为相似的子问题,直至求解出最终结果。

在递归调用中,需要考虑递归的终止条件,即递归的边界条件,以避免出现死循环或无限递归的情况。

一般来说,递归调用需要满足递归边界条件,才能够最终退出递归的循环。

二、使用递归求解最大公约数的思路假设我们要求两个数字a和b的最大公约数,我们可以利用欧几里得算法(Euclidean algorithm)来求解。

欧几里得算法的原理是,两个整数的最大公约数等于其中较小的数和两数相除所得余数的最大公约数。

我们可以通过递归的方式来应用欧几里得算法。

具体来说,我们首先比较a和b的大小,如果a小于b,则交换两个数字的位置,确保a始终大于等于b。

我们计算a除以b的余数,将b和余数作为新的两个数字,再次递归调用自己,直至余数为0。

此时,b即为所求的最大公约数。

三、具体实现下面我们给出使用递归求解最大公约数的具体实现。

```pythondef gcd(a, b):if b == 0:return aelse:return gcd(b, a % b)以上代码中,我们定义了一个名为gcd的函数,接受两个参数a和b。

用欧几里得算法求两个自然数的最大公约数c语言

用欧几里得算法求两个自然数的最大公约数c语言

用欧几里得算法求两个自然数的最大公约数c语言
欧几里得算法是一种求解两个自然数最大公约数的有效方法。

该算法的基本思想是利用辗转相除的方式,将两个自然数不断地做除法运算,直到余数为零为止。

在实现该算法时,可以使用递归或循环的方式。

以下是使用C语言实现欧几里得算法求解两个自然数最大公约数的代码示例:
```c
#include <stdio.h>
int gcd(int a, int b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
int main() {
int a, b, result;
printf('请输入两个自然数:');
scanf('%d%d', &a, &b);
result = gcd(a, b);
printf('最大公约数为:%d', result);
return 0;
}
```
在该代码中,定义了一个名为gcd的函数,用于实现欧几里得算法。

该函数的参数a和b分别表示两个自然数,函数返回值为它们的最大公约数。

在函数中,首先判断b是否为零,如果是则返回a,否则将b与a%b的结果作为参数递归调用gcd函数。

在main函数中,通过scanf函数获取用户输入的两个自然数,并调用gcd函数求解它们的最大公约数,最后使用printf函数输出结果。

使用函数求最大公约数c语言

使用函数求最大公约数c语言

使用函数求最大公约数c语言最大公约数(Greatest Common Divisor,缩写为GCD)在数学中是一个非常重要的概念。

它可以用于许多问题,如简化分数、判断两个数是否互质等。

在计算机编程中,求两个数的最大公约数是一项基本任务。

本文将介绍使用C语言编写函数来计算最大公约数的方法。

最大公约数的定义最大公约数(GCD)是两个或更多个整数的最大公因数。

两个数的公因数是能够同时整除两个数的因数,而最大公因数就是其中最大的一个。

例如:12和18的公因数为1、2、3和6,其中6是最大的公因数,因此12和18的最大公约数为6。

如果两个数没有公因数,那么它们的最大公约数为1,即它们是互质的。

求解最大公约数的方法有多种方法可以求解最大公约数,下面将介绍其中两种常见的方法。

方法一:欧几里得算法欧几里得算法,也称辗转相除法,是一种古老的算法,用于求解两个数的最大公约数。

它的基本思想是将两个数中的较大数除以较小数得到余数,然后将较小数和余数作为新的一组数,再进行相同的操作,直到余数为0为止。

此时最大公约数即为较小数。

例如,求解56和48的最大公约数,可以按照如下步骤进行:1.用56除以48,得余数8,将8和原来的除数48作为新的一组数;2.用48除以8,得余数0,此时除数8即为所求的最大公约数。

该算法的C语言实现如下:int gcd(int a, int b){if(b == 0)return a;return gcd(b, a % b);}方法二:质因数分解法质因数分解法是另一种常用的求解最大公约数的方法。

它的基本思想是将两个数分解为质数的乘积,然后将它们的公因数相乘,得到的积即为最大公约数。

例如,求解24和36的最大公约数,可以按照如下步骤进行:1. 24的质因数分解为2*2*2*3;2. 36的质因数分解为2*2*3*3;3.将它们的公因数相乘,得到的积为2*2*3=12,即为所求的最大公约数。

该算法的C语言实现如下:int gcd(int a, int b){int i, gcd = 1;for(i = 2; i <= a && i <= b; i++){if(a % i == 0 && b % i == 0){gcd *= i;a /= i;b /= i;i = 1;}}return gcd;}函数实现使用函数求解最大公约数的好处是可以将求解的代码封装在一个函数中,方便重复调用。

C语言实现求最大公约数的三种方法

C语言实现求最大公约数的三种方法

C语⾔实现求最⼤公约数的三种⽅法⽬录题⽬描述问题分析代码实现⽅法⼀:穷举法⽅法⼆:辗转相除法⽅法三:更相减损法题⽬描述求任意两个正整数的最⼤公约数问题分析最⼤公因数,也称最⼤公约数、最⼤公因⼦,指两个或多个整数共有约数中最⼤的⼀个。

a,b的最⼤公约数记为(a,b),同样的,a,b,c的最⼤公约数记为(a,b,c),多个整数的最⼤公约数也有同样的记号。

求最⼤公约数有多种⽅法,常见的有质因数分解法、短除法、辗转相除法、更相减损法。

与最⼤公约数相对应的概念是最⼩公倍数,a,b的最⼩公倍数记为[a,b]。

——百度百科最⼤公因数的求法有不少,本⽂我将采⽤穷举法、辗转相除法、更相减损法三种⽅法,求两个正整数的最⼤公约数(最⼤公因数)。

代码实现⽅法⼀:穷举法穷举法(列举法),是最简单最直观的⼀种⽅法。

具体步骤为:先求出两个数的最⼩值min(最⼤公约数⼀定⼩于等于两个数的最⼩值),接着从最⼩值min递减遍历(循环结束条件为i > 0),如果遇到⼀个数同时为这两个整数的因数,则使⽤break退出遍历(退出循环),这时的遍历值i即为两个正整数的最⼤公约数。

123 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23#include <stdio.h>/*** @brief 获取两个正整数的最⼤公因数(穷举法) * @param num1 第⼀个正整数* @param num2 第⼆个正整数* @return 最⼤公因数*/int Get_Max_Comm_Divisor(int num1, int num2) {int i = 0;//获取两个整数的最⼩值int min = num1 < num2 ? num1 : num2;//从两个数的最⼩值开始递减遍历for(i = min; i > 0; i--){//i为num1和num2的公倍数if(num1 % i == 0 && num2 % i == 0)break;}return i;}2425262728293031int main(){int num1 = 0, num2 = 0;puts("请输⼊两个正整数.");scanf("%d%d", &num1, &num2); printf("最⼤公约数为%d.\n", Get_Max_Comm_Divisor(num1, num2)); return 0;}运⾏结果⽅法⼆:辗转相除法辗转相除法⼜称欧⼏⾥得算法,是指⽤于计算两个⾮负整数a ,b 的最⼤公约数。

C语言最大公约数与最小公倍数

C语言最大公约数与最小公倍数

C语言最大公约数与最小公倍数在C语言中,可以使用欧几里得算法(辗转相除法)来计算两个数的最大公约数(GCD),然后使用最大公约数和两数乘积的关系计算最小公倍数(LCM)。

#include <stdio.h>// 定义辗转相除法函数,计算最大公约数int gcd(int a, int b) {if (b == 0) {return a;} else {return gcd(b, a % b);}}// 计算最小公倍数,使用最大公约数和两数乘积的关系int lcm(int a, int b) {return (a * b) / gcd(a, b);}int main() {int num1, num2;printf("请输入两个整数:");scanf("%d %d", &num1, &num2);printf("最大公约数为:%d\n", gcd(num1, num2));printf("最小公倍数为:%d\n", lcm(num1, num2));return 0;}在上述示例中,我们首先定义了辗转相除法的函数gcd,用于计算最大公约数。

然后,我们使用最大公约数和两数乘积的关系,定义了计算最小公倍数的函数lcm最后,我们在main函数中从用户输入读取两个整数,并调用gcd和lcm函数计算最大公约数和最小公倍数,并将结果打印输出。

示例程序的输出如下:请输入两个整数:18 24最大公约数为:6最小公倍数为:72在这个例子中,我们输入了两个整数18和24。

程序计算出它们的最大公约数为6,最小公倍数为72。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验九
一、实验内容
教材3.9 定义递归函数实现下面的Ackman函数
n+1 m=0
Acm(m,n)= Acm(m-1,1) n=0
Acm(m-1,Acm(m,n-1)) n>0,m>0
教材3.10 用递归法实现勒让德多项式:
1 n=0
Pn= x n=1
((2n-1)xPn-1(x)-(n-1)Pn-2(x))/n
教程p24 使用欧几里得算法计算两个数的最大公约数,分别用递推和递归两种算法实现
教程p26 编程:将上题以多文件方式组织,在area.h中声明各个area()函数原型,在area.cpp文件中定义函数,然后在Exp9_2中包含area.h,定义main()
函数并执行。

二、实验目的
1、掌握函数的嵌套调用好递归调用
2、掌握递归算法
3、了解内联函数、重载函数、带默认参函数的定义及使用方法
4、掌握程序的多文件组织
5、掌握编译预处理的内容,理解带参数宏定义与函数的区别
三、实验步骤
教材3.9 定义递归函数实现下面的Ackman函数
n+1 m=0
Acm(m,n)= Acm(m-1,1) n=0
Acm(m-1,Acm(m,n-1)) n>0,m>0
教材3.10用递归法实现勒让德多项式:
1 n=0
Pn= x n=1
((2n-1)xPn-1(x)-(n-1)Pn-2(x))/n
教程p24 使用欧几里得算法计算两个数的最大公约数,分别用递推和递归两种算法实现
教程p26 编程:将上题以多文件方式组织,在area.h中声明各个area()函数原型,在area.cpp文件中定义函数,然后在Exp9_2中包含area.h,定义main()
函数并执行。

四、实验数据及处理结果
#include<iostream>
using namespace std;
int Acm(int m,int n){
if(m==0) return n+1;
else{
if(n==0) return Acm(m-1,1);
else return Acm(m-1,Acm(m,n-1));
}
int main(){
int a,b;
cout<<"please imput two numbers:"<<endl;
cin>>a>>b;
cout<<"Acm(a,b)="<<Acm(a,b)<<endl;
return 0;
}
教材3.10
#include<iostream>
using namespace std;
double P(int n,double x){
if(n==0) return 1;
if(n==1) return x;
return ((2*n-1)*x*P(n-1,x)-(n-1)*P(n-2,x))/n;
}
int main(){
cout<<"P(4,1.5)="<<P(4,1.5)<<endl;
}
教程p24
实验八(2)递推法
#include<iostream>
using namespace std;
int max(int x,int y){
return(x>=y?x:y);
}
int min(int a,int b){
return(a<=b?a:b);
}
int main(){
int a,b,c,d,n;
cout<<"Please imput tow numbers"<<endl;
cin>>a>>b;
c=max(a,b);
d=min(a,b);
n=c%d;
while(n!=0){
c=d;
d=n;
n=c%d;
}
cout<<"最大公约数是"<<d<<endl;
return 0;
}
递归法:
#include <iostream>
using namespace std;
int fun(int x, int y){
if (x%y==0) return y;
else return fun(y, x%y);
}
int main( ){
int m, n, t, r;
cout<<"please imput two numbers"<<endl;
cin>>m>>n;
if(m<n) {
t=m; m=n; n=t;
}
r=fun(m, n);
cout<<"最大公约数是:"<<r<<endl;
return 0;
}
教材p26
area.h
double area(double radius=0);
double area(double a,double b);
double area(double a,double b,double h); double area(double a,double b,double c,int);
area.cpp
#include<cmath>
#define PI 3.14159
double area(double radius){
return PI *radius*radius;
}
double area(double a,double b){
return a*b;
}
double area(double a,double b,double h){ return (0.5*(a+b)*h);
}
double area(double a,double b,double c,int){ double s=0.5*(a+b+c);
return sqrt(s*(s-a)*(s-b)*(s-c));
}
exp9_2.cpp
#include<iostream>
#include<cmath>
#include"area.h"
using namespace std;
#define PI 3.14159
int main(){
cout<<"Area of point is"<<area()<<'\n';
cout<<"Area of square is"<<area(1,1)<<'\n';
cout<<"Area of trapezium is"<<area(1,0.5,1)<<'\n';
cout<<"Area of triangle is"<<area(1,sqrt(1+0.5*0.5),sqrt(1+0.5*0.5),0)<<'\n';
return 0;
}
五、思考讨论题或体会或对改进实验的建议
感觉对多文件运行结构不是很透彻,运用多文件方式与不运用是否有什么区别?。

相关文档
最新文档