求两数的最大公约数的四种方法【Java版】

Q:写一段代码,求出两个整数的最大公约数,尽量优化算法的性能

一、暴力枚举

public static int gcd(int a,int b){int big = a > b ? a : b;int small = a < b ? a : b;if(big % small == 0){return small;}for(int i = small / 2;i > 1; i++){if(small % i == 0 && big % i == 0){return i;}}return i;
}

这个方法可以实现功能,但是效率很低

假设传入的参数是 10000 和 10001,就需要循环 4999 次 

二、辗转相除法(欧几里德算法)

定理:两个正整数 a 和 b(a > b)的最大公约数等于 a 除以 b 的余数 c 和 b 之间的最大公约数

public static int gcd(int a,int b){int big = a > b ? a : b;int small = a < b ? a : b;if(big % small == 0){return small;}return gcd(big % small, small);
}

这种方法相对于暴力枚举性能上有所优化,但是存在一个问题: 

当两个整数较大时,做 a % b 取模运算的性能会比较差 

三、更相减损术 

定理:两个正整数  a 和 b(a > b)的最大公约数等于 a - b 的差值 c 和较小数 b 的最大公约数

public static int gcd(int a,int b){int big = a > b ? a : b;int small = a < b ? a : b;if(big % small == 0){return small;}return gcd(big - small, small);
}

这种方法避免了大整数取模可能出现的性能问题

但是,更相减损术依靠两数求差的方式来递归,运算的次数可能会远大于辗转相除法

更相减损术是不稳定的算法,当两数相差悬殊时,如计算 10000 和 1 的最大公约数需要递归 9999 次 

四、最终优化

结合辗转相除法和更相减损术的优势,在更相减损术的基础上使用位移运算 

总所周知,位移运算的性能非常好 

当 a 和 b 均为偶数时:

gcd(a,b) = 2 * gcd(a / 2, b / 2) = 2 * gcd(a >> 1, b >> 1) 

当 a 为偶数,b 为奇数时:

gcd(a,b) = gcd(a / 2, b) = gcd(a >> 1, b) 

当 a 为奇数,b 为偶数时:

gcd(a,b) = gcd(a, b / 2) = gcd(a, b >> 1) 

当 a 和 b 均为奇数时,先利用更相减损术运算一次: 

gcd(a,b) = gcd(b, a - b)

此时 a - b 必然是偶数,又可以继续进行位移运算 

这种方式在两数比较小时,可能看不出计算次数的优势,当两数越大时,计算次数的减少就会越明显 

public static int gcd(int a,int b){if(a == b) return a;if((a & 1) == 0 && (b & 1) == 0) return gcd(a >> 1, b >> 1) << 1;else if((a & 1) == 0 && (b & 1) != 0) return gcd(a >> 1, b);else if((a & 1) != 0 && (b & 1) == 0) return gcd(a, b >> 1);else{int big = a > b ? a : b;int small = a < b ? a : b;return gcd(big - small, small);}
}

参考资料:《漫画算法:小灰的算法之旅》

一  叶  知  秋,奥  妙  玄  心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 冲突与解决冲突

目录 1.使用 git 解决冲突 GIT 常用命令 制造冲突 解决冲突 2.使用 IDEA 解决冲突 产生冲突 解决冲突 1.使用 git 解决冲突 GIT 常用命令 命令作用git clone克隆git init初始化git add 文件名添加到暂存区git commit -m " 日志信息" 文件名提交到本地库git st…

记录一个Maxwell采集MySQL数据时报安全证书时间不通过的问题

【背景描述】 我的zk&#xff0c;kafka和Maxwell都正常启动了 此时我需要用Maxwell将MySQL的一张表user_info将其全量同步到kafka当中时发生报错&#xff0c;命令如下&#xff1a; [atguiguhadoop102 datas]$ /opt/module/maxwell/bin/maxwell-bootstrap --database gmall --…

ACE Lab 数据恢复/数据取证技术交流研讨会

2024年4月20-21日&#xff0c;ACE Lab 数据恢复/数据取证技术交流研讨会在北京举行&#xff0c;天津鸿萌科贸发展有限公司参加了这次技术研讨会。 ACE Lab 的 PC-3000 系列产品是数据恢复及取证领域的顶级工具&#xff0c;深受领域内专家的推崇。 本次技术交流带来了如下最新技…

【Python-装饰器】

Python-装饰器 ■ 简介■ 装饰器的一般写法&#xff08;闭包写法&#xff09;■ 装饰器的语法 (outer写法) ■ 简介 装饰器其实是一种闭包&#xff0c; 功能就是在不破坏目标函数原有的代码和功能的前提下为目标函数增加新功能。 ■ 装饰器的一般写法&#xff08;闭包写法&am…

自定义Vue 2双向绑定指令:实现与解析

自定义Vue 2双向绑定指令&#xff1a;实现与解析 Vue.js以其简洁的语法和强大的数据绑定功能深受开发者喜爱。其中&#xff0c;内置的v-model指令实现了输入控件与数据模型之间的双向绑定&#xff0c;简化了表单交互的处理。然而&#xff0c;在某些特定场景下&#xff0c;我们…

【Rust】——通过Deref trait将智能指针当作常规引用处理

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

分享购热潮席卷而来:解析其背后的成功密码

亲爱的朋友们&#xff0c;我是微三云的周丽&#xff0c;一名专注于私域电商模式创新的探索者。 随着数字化时代的到来&#xff0c;消费者的购物行为也在不断变化&#xff0c;因此&#xff0c;企业必须不断地探索新的ying销方式&#xff0c;以xi引用户、提升xiao售额。而最近备…

SVN泄露(ctfhub)

目录 下载安装dvcs-ripper 使用SVN 一、什么是SVN&#xff1f; 使用SVN能做什么&#xff1f; 二、SVN泄露&#xff08;ctfhub&#xff09; SVN源代码漏洞的主要原因&#xff1a; 工具准备&#xff1a;dirsearch、dvcs-ripper 网络安全之渗透测试全套工具篇&#xff08;内…

asrpro 启动流程

学术用途&#xff0c;无意冒犯&#xff0c;如有冒犯&#xff0c;敬请告之&#xff0c;侵删 使用vscode 打开&#xff0c;设置断点&#xff0c;查看启动过程&#xff0c;文档中代码有详细的注释 运行语音程序 触发程序 system_hook.c ASR_CODE 事件发生时调用 system_hook.…

深入理解VGG网络,清晰易懂

深入理解VGG网络 VGG网络是深度学习领域中一个非常经典的卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;由牛津大学的视觉几何组&#xff08;Visual Geometry Group&#xff09;提出。它在2014年的ImageNet挑战赛中取得了第二名的好成绩&#xff0c;并且在随后的许…

智慧水务能效管理系统平台/地下污水厂配电系统电气安全设计

安科瑞电气薛瑶瑶18701709087 1、引言 地下水污厂在城市建设中扮演着重要的角色,负责对城市污水和废物进行处理和排放。然而,由于地下水污厂中存在着许多危险因素,如有害气体、液体和固体废物等,因此要保证电气安全。电气安全系统是地下水污厂安全生产的重要保障措施之一,包括…

C语言进阶课程学习记录-函数参数的秘密

C语言进阶课程学习记录-函数参数的秘密 实验实验小结调用约定实验-求平均数实验-可变参数的函数小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 实验 #include <stdio.h>int func(int i, int…

MySQL学习笔记1(MySQL基础)

1.MySQL基础 1.数据库相关概念 ​ *数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储 DtaBase(DB) ​ *数据管理系统&#xff1a;操纵和管理数据库的大型软件 DataBase Management System (DBMS) ​ *SQL&#xff1a;操作关系型数据库的编程语言&#…

初始C++

1. C关键字(C98) C总计63个关键字&#xff0c; C语言32个关键字 ps&#xff1a;下面我们只是看一下C有多少关键字&#xff0c;不对关键字进行具体的讲解。后面我们学到以后再 细讲。 2. 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;…

JAVA学习笔记28(常用类)

1.常用类 1.1 包装类 1.包装类的分类 ​ 1.针对八中基本数据类型相应的引用类型–包装类 ​ 2.有了类的特点&#xff0c;就可以调用类中的方法 2.包装类和基本数据类型的转换 ​ *装箱&#xff1a;基本类型 --> 包装类型 //手动装箱 int n1 100; Integer integer ne…

【C语言__函数栈帧的创建和销毁__复习篇9】

目录 前言 一、知识补充 二、分析创建和销毁的过程 三、前言问题回答 前言 本篇主要讨论以下问题&#xff1a; 1. 编译器什么时候为局部变量分配的空间 2. 为什么局部变量的值是随机的 3. 函数是怎么传参的&#xff0c;传参的顺序是怎样的 4. 形参和实参是什么关系 5. 函数…

电商平台业务及架构演变史

不少人认为电商系统很简单&#xff0c;因为现在做电商的太多了&#xff0c;看到的电商产品也多。看来看去产品都差不多&#xff0c;没什么特别。 其实中国电商发展已有20多年历史&#xff0c;电商以销售为核心连接着研、产、供、销、服整套的信息系统体系。其中的设计并没有那…

企业公众号数量怎么申请

一般可以申请多少个公众号&#xff1f;许多用户在申请公众号时可能会遇到“公众号显示主体已达上限”的问题。这是因为在2018年11月16日对公众号申请数量进行了调整&#xff0c;具体调整如下&#xff1a;1、个人主体申请公众号数量上限从2个调整为1个。2、企业主体申请公众号数…

vue---计算属性

姓名案例 1.使用插值语法实现 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>姓名案例_插值语法实现</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js"&g…

从源码选择到国际化运营:打造成功的跨境电商网站必备指南

跨境电商网站的成功离不开经过精心策划和执行的全面计划。从源码选择到国际化运营&#xff0c;每一步都至关重要。作为跨境电商领域的专家&#xff0c;我将为您提供打造成功跨境电商网站的必备指南&#xff0c;帮助您开拓全球市场&#xff0c;提升边际收入。 选择优质的跨境电…