深根半夜里研究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的更多相关文章

  1. C 语言实例 - 求两数的最大公约数

    C 语言实例 - 求两数的最大公约数 用户输入两个数,求这两个数的最大公约数. 实例 - 使用 for 和 if #include <stdio.h> int main() { int n ...

  2. js 两数的最大公约数

    function gcd(a,b){ if (b == 0){ return a; } var r = parseInt(a % b) ; return gcd(b, r);}gcd(12,5);

  3. C语言 求两数的最大公约数和最小公倍数

    //作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ #include<stdio.h> //最大公约数 int gys(int x,int ...

  4. 浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用

    一.欧几里得算法及其证明 1.定义: 欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b): 2.证明: 设x为两整数a,b(a>=b)的最大公约 ...

  5. 浅谈Stein算法求最大公约数(GCD)的原理及简单应用

    一.Stein算法过程及其简单证明 1.一般步骤: s1:当两数均为偶数时将其同时除以2至至少一数为奇数为止,记录除掉的所有公因数2的乘积k: s2:如果仍有一数为偶数,连续除以2直至该数为奇数为止: ...

  6. 用二进制方法求两个整数的最大公约数(GCD)

    二进制GCD算法基本原理是: 先用移位的方式对两个数除2,直到两个数不同时为偶数.然后将剩下的偶数(如果有的话)做同样的操作,这样做的原因是如果u和v中u为偶数,v为奇数,则有gcd(u,v)=gcd ...

  7. .net求两个数的最大公约数和最小公倍数

    最大公约数:指两个或多个整数共有约束中最大的一个. 最小公倍数:如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数,对于两个整数来说,指该两数共有倍数中最小的一个. /// <s ...

  8. hdu 4630 查询[L,R]区间内任意两个数的最大公约数

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. K:求取两个数的最大公约数的两个算法

    相关介绍:  最大公因数,也称最大公约数.最大公因子,指两个或多个整数共有约数中最大的一个.a,b的最大公约数记为gcd(a,b).同样的,a,b,c的最大公约数记为gcd(a,b,c),多个整数的最 ...

随机推荐

  1. 使用XTU降低CPU功耗,自动执行不失效

    INTEL出品的XTU可以用来做软超频操作,给CPU/GPU加电压超频,也可以通过降低CPU/GPU电压来减少功耗. 以前用XTU设置好了之后,过一段时间就自动失效了,最近失效的频率突然很高,于是找了 ...

  2. 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 ...

  3. POI2007 MEG-Megalopolis [树状数组]

    MEG-Megalopolis 题目描述 Byteotia has been eventually touched by globalisation, and so has Byteasar the ...

  4. 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 ...

  5. 带依赖包的maven打包配置

    转载自:http://outofmemory.cn/code-snippet/2594/carry-yilai-bao-maven-dabao-configuration 可以在maven的packa ...

  6. ubuntu12.04回归到经典的gnome界面

    要想删除Unity恢复到经典Gnome桌面也很简单,几乎就是一条命令的事情--命令这种东西虽然不直观,但非常可靠和快捷,同时按住Ctrl+Alt+T三个键,调出系统终端,输入: sudoapt-get ...

  7. 【洛谷 P1653】 猴子 (并查集)

    题目链接 没删除调试输出,原地炸裂,\(80\)->\(0\).如果你要问剩下的\(20\)呢?答:数组开小了. 这题正向删边判连通性是很不好做的,因为我们并不会并查集的逆操作.于是可以考虑把断 ...

  8. npm install 报node-sass错误

    Node Sass could not -bit with Node.js .x Found bindings for the following environments: - OS X -bit ...

  9. [转]如何整理Linux磁盘碎片,竟与Windows的方式大不同 返回操作系统首页

    Linux 系统永远不需要整理磁盘碎片的神话相信很多人都听说过.由于 Linux 采用了优秀的日志文件系统(ext2.ext3.ext4, btrfs等),在绝大多数情况下确实是不需要进行磁盘碎片整理 ...

  10. (转)Vim 脚本语言

    2012 年 10 月 20 日 by name5566 Categories: Computer Science, Tools 参考文献列表: http://vimdoc.sourceforge.n ...