[辗转相除法]求最大公因子

目录

一、递归版本

二、算法正确性证明

三、非递归版本


一、递归版本

/* 
 * Copyright (c) 2014, 烟台大学计算机与控制工程学院
 * All rights reserved.
 * 作    者:何小乐
 * 完成日期:2014/10/29
 * 修改日期:2018/10/3
 * 版 本 号:v1.1
 *
 * 名字:gcd_recursive
 * 描述:使用递归的方法得到两个整型数的“最大公因子”
 * 参数约定: a != 0
             b == 0时表示此时a为两个数的最大公因子
 * 返回值意义:0表示参数异常
 */
int gcd_recursive(int a, int b)
{
    if(a == 0)
        return 0;

    if(b == 0)
        return a;

    return gcd_recursive(b, a % b);
}

二、算法正确性证明

证明对 a, b 求最大公因子可以转化为对 b, a % b 求最大公因子

| a | > | b |(| a | < | b |时交换 a, b 的位置继续证明)(取绝对值的原因是考虑到 a, b 可能是负数)

a, b 的最大公因子为 g ( | g | >= 1, 因为 a, b 至少有 1 作为最大公因子)

则 a, b 可以表示为

a = m * g

b = n * g

a % b 的商为 x,余数为 y,则有

a = b * x + y

y = a - b * x = m * g - n * g * x = ( m - n * x ) * g

因为

1 <= | a, b, y 的最大公因子 | <= | a, b 的最大公因子 |(| 3个数的最大公因子 | <= | 任意其中2个数的最大公因子 |)

a, b 的最大公因子为 g

g 是 y 的因子

所以

g 也是 a, b, y 的最大公因子

因为

| a | > | b | >= | y |

所以

a, b 求解最大公因子可以转化为对2者的更小规模 b, y 即 b, a % b 求解

证毕

 

三、非递归版本

递归版本随着递归深度的增加而用于存储函数信息的内存变大

/*
 * 名字:gcd
 * 描述:gcd_recursive的非递归版本
 * 参数约定:同gcd_recursive
 * 返回值意义:同gcd_recursive
 */
int gcd(int a, int b)
{
    if (a == 0)
        return 0;
    
    if (b == 0)
        return a;

    int r;

    while ( (r = a % b) != 0) // 等于0时代表a可以被b整除,即b为a,b的最大公因子
    {
        a = b;
        b = r;
    }

    return b;
}

 

你可能感兴趣的:(算法)