【本文链接】

http://www.cnblogs.com/hellogiser/p/efficient-method-to-solve-gcd-problem.html

【题目】

  求两个正整数的最大公约数Greatest Common Divisor (GCD)。如果两个正整数都很大,有什么简单的算法吗?例如,给定两个数1 100 100 210 001, 120 200 021,求出其最大公约数。

【解法】


【1. 辗转相除法】

辗转相除法:f(x,y) = f(y , x % y)(x>y)

f(42,30) = f(30,12) = f(12,6) = f(6,0) = 6

【代码】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/7/8
*/

int gcd(int x, int y)
{
    if(x < y)
        return gcd(y, x);
    )
        return x;
    else
        return gcd(y, x % y);
}

此方法中用到了取模运算,对于大整数而言,取模运算(其中用到了除法)开销是非常昂贵的,将成为整个算法的瓶颈。


【2. 辗转相减法】

辗转相减法:f(x,y) = f(y, x-y) (x>y)

f(42,30) = f(30,12) = f(12,18) = f(18,12) = f(12,6)=f(6,6)=f(6,0)=6

【代码】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/7/8
*/

int gcd(int x, int y)
{
    if(x < y)
        return gcd(y, x);
    )
        return x;
    else
        return gcd(y, x - y);
}

这个算法免去了大整数除法的繁琐,但同样也有不足之处。最大的瓶颈是迭代的次数过多,如果出现(1 000 000 000,1)这类情况,那就相当让人郁闷了。


【3. 奇偶法】

奇偶法:

此种方法是将解法1)和解法2)结合起来,降低计算复杂度的同时也降低迭代次数。

1:若 x, y均为偶数,f (x,y) = 2 * f(x / 2, y / 2) = 2 * f(x >> 1, y >> 1)

2:若x为偶,而y为奇,f (x , y )  = f (x / 2, y) = f ( x >> 1, y)

3:若x为奇,y为偶,f ( x, y)  = f (x , y / 2) = f(x , y >> 1)

4:若x,y均为奇,f ( x, y ) = f (y , x - y)

在f(x, y) = f(y, x - y)之后,(x - y)是一个偶数,下一步一定会有除以2的操作。

因此最坏情况下时间复杂度为O(log2 (max(x,y)))。

f (42 , 30 ) = 2 * f (21,15)

= 2 * f (15,6)

= 2 * f (15,3)

= 2 * f (3,12)  =2 * f (12,3)

= 2 * f (6,3)

= 2 * f (3,3)

= 2 * f (3,0)

= 2 * 3

= 6

代码】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
/*
    version: 1.0
    author: hellogiser
    blog: http://www.cnblogs.com/hellogiser
    date: 2014/7/8
*/

bool IsEven(int x)
{
    ;
}

int gcd(int x, int y)
{
    if(x < y)
        return gcd(y, x);
    )
        return x;
    else
    {
        if(IsEven(x))
        {
            if(IsEven(y)) //case 1,x,y均为偶数
);
            else  //case 2,x为偶,y为奇
, y);
        }
        else
        {
            if(IsEven(y)) //case 3,x为奇,y为偶
);
            else  //case 4,x,y均为奇
                return gcd(y, x - y);
        }
    }
}

【参考】

http://blog.csdn.net/ajioy/article/details/7478008

http://blog.csdn.net/rein07/article/details/6739688

【本文链接】

http://www.cnblogs.com/hellogiser/p/efficient-method-to-solve-gcd-problem.html

2.7 编程之美--最大公约数的3种解法[efficient method to solve gcd problem]的更多相关文章

  1. java多线程编程题之连续打印abc的几种解法

    一道编程题如下: 实例化三个线程,一个线程打印a,一个打印b,一个打印c,三个线程同时执行,要求打印出6个连着的abc 题目分析: 通过题意我们可以得出,本题需要我们使用三个线程,三个线程分别会打印6 ...

  2. 【编程之美】2.5 寻找最大的k个数

    有若干个互不相等的无序的数,怎么选出其中最大的k个数. 我自己的方案:因为学过找第k大数的O(N)算法,所以第一反应就是找第K大的数.然后把所有大于等于第k大的数取出来. 写这个知道算法的代码都花了2 ...

  3. 【编程之美】CPU

    今天开始看编程之美 .第一个问题是CPU的使用率控制,微软的问题果然高大上,我一看就傻了,啥也不知道.没追求直接看答案试了一下.发现自己电脑太好了,4核8线程,程序乱飘.加了一个进程绑定,可以控制一个 ...

  4. 编程之美_1.1 让CPU占用率曲线听你指挥

    听到有人说让要写一个程序,让用户来决定Windows任务管理器的CPU占用率. 觉得很好奇.但第一个想法就是写个死循环.哈哈.不知道具体的占用率是多少,但至少能保证在程序运行时,CPU的占用率终会稳定 ...

  5. 编程之美的2.17,数组循环移位 & 字符串逆转(反转) Hello world Welcome => Welcome world Hello

    代码如下:(类似于编程之美的2.17,数组循环移位) static void Main(string[] args) { string input = "Hello World Welcom ...

  6. [质疑]编程之美求N!的二进制最低位1的位置的问题

    引子:编程之美给出了求N!的二进制最低位1的位置的二种思路,但是呢?但是呢?不信你仔细听我道来. 1.编程之美一书给出的解决思路 问题的目标是N!的二进制表示中最低位1的位置.给定一个整数N,求N!二 ...

  7. 编程之美 两个叶子的节点之间 最大距离 变种 leecode

    提交地址: https://oj.leetcode.com/problems/binary-tree-maximum-path-sum/ 说一下思路http://www.cnblogs.com/mil ...

  8. 编程之美之数独求解器的C++实现方法

    编程之美的第一章的第15节.讲的是构造数独.一開始拿到这个问题的确没有思路, 只是看了书中的介绍之后, 发现原来这个的求解思路和N皇后问题是一致的. 可是不知道为啥,反正一開始确实没有想到这个回溯法. ...

  9. 《编程之美》之如何控制CPU的暂用率固定在50%

    <编程之美>第一章 让CPU暂用率听你指挥的粗糙实现,如何控制CPU的暂用率固定在50% #include <stdio.h> #include <Windows.h&g ...

随机推荐

  1. Node_JS

    //http://www.nodebeginner.org/index-zh-cn.html#how-our-server-handles-requests 按照这个页面的例子写的,留作笔记//ind ...

  2. Java设计模式-模板方法模式(Template Method)

    解释一下模板方法模式,就是指:一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用,先看个关系 ...

  3. JSP页面中 <base href="<%=basePath%>">

    base标记是一个基链接标记,是一个单标记.用以改变文件中所有连结标记的参数内定值.它只能应用于标记<head>与</head>之间.你网页上的所有相对路径在链接时都将在前面加 ...

  4. 洛谷P2925 [USACO08DEC]干草出售Hay For Sale

    题目描述 Farmer John suffered a terrible loss when giant Australian cockroaches ate the entirety of his ...

  5. hdu acmsteps 2.1.3 Cake

    Cake Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  6. java链接到mysql

    原文出自 http://qq163230530.blog.163.com/blog/static/4289250620081186262719/ eclipse 下载安装后 新建web项目 首先配置服 ...

  7. js获取页面url的方法

    我们可以用javascript获得其中的各个部分 1, window.location.href 整个URl字符串(在浏览器中就是完整的地址栏) 本例返回值: http://ifisker.com/b ...

  8. URLDecoder与URLEncoder

    网页中的表单使用POST方法提交时,数据内容的类型是 application/x-www-form-urlencoded,这种类型会: 1.字符"a"-"z", ...

  9. 使用key链接远程Git仓库

    使用密钥来访问Git仓库比密码安全多了,只要把公钥配置在远程端,把密钥放到~/.ssh/里以id_rsa命名即可. 不过有人要问如果有多个仓库,而且用了不同密钥怎么办? 这时候可以在~/.ssh/文件 ...

  10. linux 下安装memcached与php的memcache扩展

    1. 在线安装 yum install memcached: 源代码安装 wget http://memcached.org/latest 下载最新版本 tar -zxvf memcached-1.x ...