关于两数的最大公约数gcd
深根半夜里研究C++的语法,在弄到关于函数的定义 这一部分时突然想写个试试,就拿比较熟悉的gcd来好了。
活这么久gcd一直是用辗转相除法(或者说欧几里得算法)得出的,根据《算法导论》第三版的中文页码P547给出的伪代码,很容易就得出C++的写法。
int gcd(int a,int b){ if(b==0) return a; else return gcd(b,a % B); }
However----
当a,b比较大的时候显得特别慢,所以出现了来自《九章算术》中的更相减损术来求gcd。(怕是活久见的实例。。。)
更相减损术的代码如下:
int gcd(int a,int b){ if(a==b) return a; else if(a<b) return gcd(b-a,a); else return gcd(a-b,b); }
换句话说,其原理可以被称为“辗转相减法”【笑】。根据gcd(a,b)=gcd(|a-b|,min(a,b)),然后设定一下边界(即两个相等的数,其gcd值为本身),就有了。具体证明不知道【喂太草率了吧!!】,反正没问题可以用就是了。
But----
当|a-b|比较大的时候,很明显递归次数比较多,这不是想要的结果。再看一遍原文:
可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。
好了,【作为一名文科生恬不知耻地笑了】其实原文的目的是为了约分,“可半者半之”就是说能约2就约2,然后不能约2了再找gcd约分。
所以分类讨论一下:
- 两数皆偶:美滋滋,易有gcd(a,b)=2×gcd(a÷2,b÷2)
- 一奇一偶:只要想象一下类似约分一个分数like 9÷30,很显然有gcd(a,b)=gcd(a,b÷2),因为偶数除以2只是排除掉了一个因子2,而2又不可能是奇数的因子,所以可以得到这个等式成立
- 两数皆奇:那怎么办呐?【笑】有小学奥数可知在整数范围内,奇数-奇数=偶数。所以跑一次“辗转相减法”以后,问题就转化为了上一种情况
所以ok,final版本的gcd就出来了,大半夜的写错了别打我啊。。。
int gcd(int a,int b){ if(a==b) return a; else switch (check(a,b)){ case 0:return 2*gcd(a/2,b/2);break; case 1:return gcd(a,b/2);break; case 2:return gcd(a/2,b);break; case 3:return gcd(abs(a-b),min(a,b));break; } }
有必要说明一下的是check函数检验的是将要参与gcd运算的两数的奇偶性,0就是同偶,1和2都是一奇一偶只不过位置有区别,3就是同奇的情况;abs是绝对值函数,min则返回两数间较小的一个。
关于两数的最大公约数gcd的更多相关文章
- C 语言实例 - 求两数的最大公约数
C 语言实例 - 求两数的最大公约数 用户输入两个数,求这两个数的最大公约数. 实例 - 使用 for 和 if #include <stdio.h> int main() { int n ...
- js 两数的最大公约数
function gcd(a,b){ if (b == 0){ return a; } var r = parseInt(a % b) ; return gcd(b, r);}gcd(12,5);
- C语言 求两数的最大公约数和最小公倍数
//作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ #include<stdio.h> //最大公约数 int gys(int x,int ...
- 浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用
一.欧几里得算法及其证明 1.定义: 欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b): 2.证明: 设x为两整数a,b(a>=b)的最大公约 ...
- 浅谈Stein算法求最大公约数(GCD)的原理及简单应用
一.Stein算法过程及其简单证明 1.一般步骤: s1:当两数均为偶数时将其同时除以2至至少一数为奇数为止,记录除掉的所有公因数2的乘积k: s2:如果仍有一数为偶数,连续除以2直至该数为奇数为止: ...
- 用二进制方法求两个整数的最大公约数(GCD)
二进制GCD算法基本原理是: 先用移位的方式对两个数除2,直到两个数不同时为偶数.然后将剩下的偶数(如果有的话)做同样的操作,这样做的原因是如果u和v中u为偶数,v为奇数,则有gcd(u,v)=gcd ...
- .net求两个数的最大公约数和最小公倍数
最大公约数:指两个或多个整数共有约束中最大的一个. 最小公倍数:如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数,对于两个整数来说,指该两数共有倍数中最小的一个. /// <s ...
- hdu 4630 查询[L,R]区间内任意两个数的最大公约数
No Pain No Game Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- K:求取两个数的最大公约数的两个算法
相关介绍: 最大公因数,也称最大公约数.最大公因子,指两个或多个整数共有约数中最大的一个.a,b的最大公约数记为gcd(a,b).同样的,a,b,c的最大公约数记为gcd(a,b,c),多个整数的最 ...
随机推荐
- 使用XTU降低CPU功耗,自动执行不失效
INTEL出品的XTU可以用来做软超频操作,给CPU/GPU加电压超频,也可以通过降低CPU/GPU电压来减少功耗. 以前用XTU设置好了之后,过一段时间就自动失效了,最近失效的频率突然很高,于是找了 ...
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) A
A. Little Artem and Presents time limit per test 2 seconds memory limit per test 256 megabytes input ...
- POI2007 MEG-Megalopolis [树状数组]
MEG-Megalopolis 题目描述 Byteotia has been eventually touched by globalisation, and so has Byteasar the ...
- codeforces 719C. Efim and Strange Grade
C. Efim and Strange Grade time limit per test 1 second memory limit per test 256 megabytes input sta ...
- 带依赖包的maven打包配置
转载自:http://outofmemory.cn/code-snippet/2594/carry-yilai-bao-maven-dabao-configuration 可以在maven的packa ...
- ubuntu12.04回归到经典的gnome界面
要想删除Unity恢复到经典Gnome桌面也很简单,几乎就是一条命令的事情--命令这种东西虽然不直观,但非常可靠和快捷,同时按住Ctrl+Alt+T三个键,调出系统终端,输入: sudoapt-get ...
- 【洛谷 P1653】 猴子 (并查集)
题目链接 没删除调试输出,原地炸裂,\(80\)->\(0\).如果你要问剩下的\(20\)呢?答:数组开小了. 这题正向删边判连通性是很不好做的,因为我们并不会并查集的逆操作.于是可以考虑把断 ...
- npm install 报node-sass错误
Node Sass could not -bit with Node.js .x Found bindings for the following environments: - OS X -bit ...
- [转]如何整理Linux磁盘碎片,竟与Windows的方式大不同 返回操作系统首页
Linux 系统永远不需要整理磁盘碎片的神话相信很多人都听说过.由于 Linux 采用了优秀的日志文件系统(ext2.ext3.ext4, btrfs等),在绝大多数情况下确实是不需要进行磁盘碎片整理 ...
- (转)Vim 脚本语言
2012 年 10 月 20 日 by name5566 Categories: Computer Science, Tools 参考文献列表: http://vimdoc.sourceforge.n ...