zoukankan      html  css  js  c++  java
  • 【算法】欧几里德算法--求最大公约数

    预备知识

    因子(除数)

    如果有整数 n,a,b 。a和b都不为0 ,且 有 n = a*b ,则说a(或者b,以下省略说明)为n的一个因子,或者说a能整除n。

    特别的:任何非0整数都是0的因子,所以一般我们不会去求0的因子。

    如:3 的因子有  1, -1 ,  3 ,  -3 。然而我们一般只考虑正数因子,因为负数因子和正数因此没有本质上的区别,只是符号不同而已。

    素数:素数(也叫质数)的定义是,如果整数p的因子 只有 ±1 和   ±p,则它就是素数 。特别的:0 和1既不是素数,也不是合数。

             合数一定能分解为 若干个 素数相乘的形式。如 27 = 3x3x3 ,155 = 5x31

    模运算

    a为正整数,且可以表示为: a = q*m+r  ( r和q都是整数,且0<= r  < q ), 则说:  a mod q = r    。

    例如: 7 mod 4 =  3      ,因为 7= 1*4 +3

    我们并没有给出负数的模运算定义,因为它的定义不统一,也很少使用。但是要注意的是,在C/C++ 和 Java中,模运算的结果的符号和第一个操作数的符号相同。也就是说 a %  b 的结果和 a 的符号相同。

    模运算是很有作用的,例如,任何 正整数 mod  m ,将会把他们映射到集合{0,1,2,...m-1}上。 

    欧几里德算法求最大公约数

    将a ,b的公约数运算表示为函数gcd(a,b) 的返回值。a,b是不全为 0 的 非负数,且a >= b。

    则  gcd(a,b)  =  gcd(b, a  mod  b)  ,可以看见是一个递归调用,调用结束的条件是 : 第二个参数为 0,则返回的结果为 第一个参数。

    也就是说:gcd(m,0) =  m。

    代码实现:

    int gcd1(int a, int b)     //使用递归
    {
        assert(a >= b);
    
        if (b == 0) 
            return a;
        else 
            return gcd1(b, a%b);
    
    
    }
    
    
    int gcd2(int a, int b)   //使用循环
    {
        assert(a >= b);
        int r;
    
        while (b != 0)
        {
            r = a%b;
            a = b;
            b = r;
        }
        return a;
    }
  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/lulipro/p/6684437.html
Copyright © 2011-2022 走看看