关于两数的最大公约数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),多个整数的最 ...
随机推荐
- BZOJ day2_plus
大半夜的刷b站,好爽啊... 突破十九题 1008105110591088117911911192143218761951196821402242243824562463276128184720
- Spring源码解析-基于注解依赖注入
在spring2.5版本提供了注解的依赖注入功能,可以减少对xml配置. 主要使用的是 AnnotationConfigApplicationContext: 一个注解配置上下文 AutowiredA ...
- The xor-longest Path [Trie]
The xo-longest Path 题目描述 给定一棵\(n≤100 000\)个点的带权树,求树上最长的异或和路径. 输入 多组数据.每组数据第一行一个整数n(\(1≤n≤100 00\),接下 ...
- Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)
D. Petya and Array 题目链接:https://codeforces.com/contest/1042/problem/D 题意: 给出n个数,问一共有多少个区间,满足区间和小于t. ...
- spring4.3注解
Spring4.3中引进了 {@GetMapping.@PostMapping.@PutMapping.@DeleteMapping.@PatchMapping},分别对应这个查询,插入,更新,删除 ...
- java web标签
一:国庆结束了,回来上班,结果老大说过两天才出差,所以这两天就用来补自己不太懂的知识或者以前没有熟悉的知识,jsp的标签就是,因为在项目中自己封装了一些标签,但是我自己只是会用,真正的原理性的东西我还 ...
- 给 ecplise 配置struts2配置环境
下面介绍在Eclipse中配置Struts2的过程: 一.下载Struts2,因为Struts2是开源的,百度或者google一下就可以找到下载地址.我下载的是struts-2.3.1.2版本 的,解 ...
- JSP页面中格式化日期为指顶格式
有时候在页面中显示直接从数据库获取的日期时候会出现英文的日期格式.比如:
- Linux MMC介绍
1. 介绍 Linux中,将包括MMC.SD.SDIO统称为MMC子系统 MMC子系统从功能上可分为三个层次 - card层: Card驱动, 或称client驱动 - core层: MMC的核心层, ...
- android 调试 native 程序的方法
一.背景 首先说需求,这个需求非常常见,就是android上需要的一个功能,linux已经有开源代码而且非常稳定,希望能直接porting过去使用,这个程序是pure c 的代码,也就是说,跟andr ...