求最大公约数的几种算法分析

题目——求两个整数的最大公约数

思路1、穷举算法

public static voidmain(String[] args) throws IOException {
Scannerscanner = new Scanner(System.in);
inta = scanner.nextInt();
intb = scanner.nextInt();
System.out.println("开始时间是"+System.currentTimeMillis());
System.out.println(gcd(a,b));
System.out.println("结束时间是"+System.currentTimeMillis());
}

private static intgcd(int a, int b) {
intgcd = 1;
for(int i = 2; i <=a  && i<=b;i++) {
if(a%i == 0 && b%i == 0) {
gcd= i;
}
}
returngcd;
}

验证——

用两个数字来进行验证,同时计算开始计算前的时刻和计算完毕的时刻,可以得到该算法需要的运行时间。

3450012

2100324

开始时间是1401859016757

12

结束时间是1401859016775

明显,该算法的复杂度是O(N),所需要的运行时间是18毫秒。比较长。需要改进。

思路2——改进后的穷举算法

这里假设,数字a比b大,数字a的除数不可能比a/2还大。因此,我们从a/2开始穷举找起,会更快。但是考虑到一种情况就是,数字b有可能是a的除数。所以,改进后的算法如下——

private static intgcd(int a, int b) {
intgcd = 1;
intm=0,n =0;
//m存储较大值,n存储较小值
if(a>b){
m= a;
n= b;
}else{
m= b;
n= a;
}
if(m%n == 0) {
gcd= n;
returngcd;
}

for(int i = n/2; i>=1; i--) {
if(m%i == 0 && n%i == 0) {
gcd= i;
break;
}
}
returngcd;
}

验证——

3450012

2100324

开始时间是1401859092824

12

结束时间是1401859092834

可以看出,执行时间上明显减少了,只需要10毫秒。假如a>b,
实际上这个for循环只是最多执行n/2次,比第一个完全穷举要缩短一半的时间。

尽管它的算法复杂度依然是O(N)。

但是,第二个算法只是改进了的穷举算法,效率依然不够高。比之更好些的一个算法是

思路3——进欧几里算法

这是上世纪的一个数学家进欧几里得发现的一个算法。用gcd(m,n)来表示整数m,n的最大公约数,则算法的定义为:

  • 如果m%n == 0,那么gcd(m,n)
    就是n;
  • 否则,gcd(m,n)
    就是gcd(n,m%n)

private static intgcd(int a, int b) {
intm=0,n =0;
//m存储较大值,n存储较小值
if(a>b){
m= a;
n= b;
}else{
m= b;
n= a;
}
if(m%n == 0) {
returnn;
}else{
returngcd(n,m%n);
}
}
 

验证——

3450012

2100324

开始时间是1401858942252

12

结束时间是1401858942252

可以看到,进欧几里的算法比前两个算法快很多,执行时间在1毫秒以内。这是很不错的效率。

求最大公约数的几种算法分析

时间: 2024-12-24 05:49:43

求最大公约数的几种算法分析的相关文章

求最大公约数的三种方法

一.最大公约数与最小公倍数 最大公约数,属于数论所探究的内容. 最大公约数可以通过下面的三种方法求出来. 最小公倍数呢,它与最大公约数的乘机为所求数之积. 比如求  x,y的最大公约数和最小公倍数 记住这个公式: x*y=最小公倍数*最大公约数 二.求最大公约数的三种方法 ①辗转相除法 算法流程图 int measure(int x, int y) { int z = y; while(x%y!=0) { z = x%y; x = y; y = z; } return z; } 运行结果: ②辗

求最大公约数的两种解法(欧几里得算法和素数分解)

最大公约数的两种解法(欧几里得算法和素数分解) 方法一: 欧几里得算法,又称辗转相除法 定理(欧几里得算法):设a和b是正整数,则存在最大求最大公因子d=(a,b)的一种算法,且存在求一组整数s,t使得d = sa+tb 举个例子:求168和60的最大公约数? 168 = 2 * 60 + 48 60  = 1 * 48 +12 48  = 4 * 12 由此得最大公约数为12 关于最大公倍数 C语言程序代码:很简单就不加注释了 #include<stdio.h> #define SWAP(a

js求最大公约数的两种方法

1.辗转相除法 function commonDivisor1(num1,num2) { if ((num1-num2) < 0) { var k = num1; num1 = num2; num2 = k; } while (num2 !=0) { var remainder = num1%num2; num1 = num2; num2 = remainder; } return num1; } 2.更相减损法 function commonDivisor2(num1,num2) { var

求一个数的最大公约数的三种思路——解题笔记

求一个数的最大公约数的三种思路--解题笔记 编程之美上的题目:求一个数的最大公约数. 这道题目有三种解题思路,总结如下: 思路一: 直接使用辗转相除法,这个不多介绍,代码如下: // 直接辗转相除法 int gcd1(int a, int b) { for(int m = a%b; m != 0; m = a%b) { a = b; b = m; } return b; } 分析:辗转相除法需要用到数值之间的取余运算,这是非常耗时间的. 思路二: 改进辗转相除法中取余(除法)运算,改为减法.这里

记一种求最大公约数的方法

除了短除,还有下面两种方法求最大公约数,不但在数学中显得简单,而且在编程中有很好的效果 尤其是特别适合于编程... 先放文字说明: 1.更相减损法 第一步:任意给定两个正整数:判断它们是否都是偶数.若是,则用2约简:若不是则执行第二步. 第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数.继续这个操作,直到所得的减数和差相等为止. 则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数. 其中所说的“等数”,就是最大公约数.求“等数”的办法是“更相减损”法.所以

多种方法求最大公约数+求最小公倍数

本文将给出求两个数a和b的最大公约数的几种可行方法. 方法一:辗转相除法 算法分析:有两个数a和b,用辗转相除法. 不妨设a>b, 首先求a和b的余数,b赋值给a,余数赋值给b: 重复以上操作,直到余数为0: b值即为两数的最大公约数. 代码: 1 int zdgys(int a,int b) 2 { 3 int temp; 4 if( a<0 ) a=-a; 5 if( b<0 ) b=-b; 6 if( a<b ) { temp=a;a=b;b=temp; } // 让a>

求最大公约数和最小公倍数

学习C++入门级的题目,求最大公约数和最小公倍数,这里介绍两种求最大公约数的方法,即辗转相除法和辗转相减法.辗转相除法的原理自行百度,辗转相减法的原理就是只要两数不想等就用大数减小数,直至相等,求最小公倍数的方法就是用两数的乘积除以最大公约数. #include<iostream> using namespace std; int maxf(int a,int b)//辗转相减法 { while(a != b) { if(a > b) return a = a - b; else ret

java求最大公约数(分解质因数)

下面是四种用java语言编程实现的求最大公约数的方法: package gcd; import java.util.ArrayList; import java.util.List; public class gcd { public static void main(String[] args) { long startTime; long endTime; long durationTime; int[] testArray1 = new int[]{784, 988, 460, 732,

求乘法逆元的几种方法

(数学渣,下面的文字可能有误,欢迎指教)乘法逆元的定义貌似是基于群给出的,比较简单地理解,可以说是倒数的概念的推广.记a的关于模p的逆元为a^-1,则a^-1满足aa^-1≡ 1(mod p) 加减乘与模运算的顺序交换不会影响结果,但是除法不行.有的题目要求结果mod一个大质数,如果原本的结果中有除法,比如除以a,那就可以乘以a的逆元替代. 在mod p的运算中,a存在乘法逆元当且仅当a与p互质.一般题目给的是一个大质数,所以只要a不是p的倍数,就以求乘法逆元. 目前了解到的求法有三种:1.扩展