最大公约数的算法
时间:2022-05-04
本文章向大家介绍最大公约数的算法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
算法的原理:
对于辗转相除法:i和j的最大公约数,也就是i和j都能够除断它。换句话讲,就是i比j的n倍多的那个数k(i = j*n + k,即i % j = k)应该也是最大公约数的倍数。所以就能转换成求k和j的最大公约数。同理,对于更相减损术,同样的道理,i比j大的部分也是最大公约数的倍数。
代码:
1 /**
2 * 求最大公约数算法汇总
3 *
4 */
5 public class GCD {
6 public static void main(String[] args) {
7 GCD gcd = new GCD();
8 gcd.gcd1(43, 45);
9 gcd.gcd2(64, 80);
10 gcd.gcd3(45, 81);
11 }
12
13
14 /**
15 * 第三种方法:更相减损术 + 辗转相除法,即
16 * 当a和b均为偶数,gcb(a,b) = 2*gcb(a/2, b/2) = 2*gcb(a>>1, b>>1)
17 * 当a为偶数,b为奇数,gcb(a,b) = gcb(a/2, b) = gcb(a>>1, b)
18 * 当a为奇数,b为偶数,gcb(a,b) = gcb(a, b/2) = gcb(a, b>>1)
19 * 当a和b均为奇数,利用更相减损术运算一次,gcb(a,b) = gcb(b, a-b), 此时a-b必然是偶数,又可以继续进行移位运算。
20 */
21 private void gcd3(int i, int j) {
22 System.out.println("The greatest common divisor is:" + doubleGcd(i, j));
23 }
24
25 private int doubleGcd(int i, int j) {
26 if (i % j == 0) {
27 return j;
28 }
29
30 if ((i&1) == 0 && (j&1) == 0) {
31 // 都是偶数
32 return doubleGcd(i >> 1, j >> 1) << 1;
33 } else if ((i&1) == 0 && (j&1) != 0) {
34 // i为偶数,j为奇数
35 return doubleGcd(i >> 1, j);
36 } else if ((i&1) != 0 && (j&1) == 0) {
37 // i为奇数,j为偶数
38 return doubleGcd(i, j >> 1);
39 } else {
40 // i和j都为奇数
41 return doubleGcd(i, i > j ? i - j : j - i);
42 }
43 }
44
45
46 /**
47 * 第二种方法:九章算术的更相减损术,即如果i>j,那么先用i-j得到其差k.然后将问题转换成求k和m的最大公约数.依此类推,直到差为0.
48 * 这个方法也有一个问题,就是如果i和j想差的比较大,那么这个方法存在较高的时间复杂度.
49 */
50 private void gcd2(int i, int j) {
51 if (i < j) {
52 gcd2(j, i);
53 return;
54 }
55
56 int k = i - j;
57 if (k == 0) {
58 System.out.println("The greatest common divisor is:" + j);
59 return;
60 } else {
61 if (k >= j) {
62 gcd2(k, j);
63 } else {
64 gcd2(j, k);
65 }
66 }
67 }
68
69 /**
70 * 第一种方法:辗转相除法, 即如果i>j, 那么先用i%j得到余数k.将问题转换成求k和m的最大公约数.依此类推,直到余数为0.
71 * 该方法有一个比较大的问题问题是取模的性能。
72 */
73 private void gcd1(int i, int j) {
74 // 确保n>m
75 if (i < j) {
76 gcd1(j, i);
77 return;
78 }
79
80 int k = i%j;
81 if (k == 0) {
82 System.out.println("The greatest common divisor is:" + j);
83 return;
84 } else {
85 if (k >= j) {
86 gcd1(k, j);
87 } else {
88 gcd1(j, k);
89 }
90 }
91 }
92 }
- Jquery 事件冒泡
- Vue2的单元测试与调试技术
- silverlight beta 2 将在本周末发布.
- [Silverlight 4 RC]WebBrowser概览
- 英文域名chosen.com超22万元易主
- 简单介绍Docker的架构特性与局限
- .NET4.0下网站应用程序用UrlRewriter.dll重写无后缀路径 (在IIS7.5中的配置方法)
- 微信搜索新发现:iPhone 内存不足看这里!
- 建立可扩展的silverlight 应用框架 step-6
- .NET4.0下网站应用程序用UrlRewriter.dll重写无后缀路径 (在IIS7.5中的配置方法)
- 苹果为你的心跳开发一个读者
- 建立可扩展的silverlight 应用框架 step-5
- 安卓 iOS 版双双更新!还带来一大波小游戏
- 建立可扩展的silverlight 应用框架 step-4
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP中的类
- PHP获取表单textarea数据中的换行问题
- Numpy根据Bool值挑选数组中元素
- MySQL获取每个分类下面的前三条数据
- windows宿主机如何SSH连接VMware的Linux虚拟机
- np.random.rand均匀分布随机数和np.random.randn正态分布随机数函数使用方法
- Java FileReader使用相对路径读取文件
- MySQL批量插入数据库实现语句性能分析
- np.repeat用法
- MySQL优化INSERT的性能
- PHP在函数体中传递与接收参数
- 使用Arraylist将数组中元素随机均等乱序分为N个子数组
- PHP中abstract 和 interface的区别
- PHP5中的魔术方法
- 一起来学演化计算-matlab基本函数randn,rand, orth