求最大公约数是一常见的数学问题,数学思维中的常用求法有指数分解、短除法、辗转相除和更相减损法,其中前两个算法通过代码实现的效率是非常低的,我能想到的方法只有首先就需要一个求质数算法的表达式来表示无穷大的质数集合,然后再试模判断,成功后进行分解。在这里我们主要研究后两个算法的设计与C语言的实现。
1、辗转相除法
其方法顾名思义,就是大数模小数取余,再用余数与小数进行比较,继续重复大数模小数取余的操作,直到大数模小数为0时,小数就是这两个数的最大公约数,又称欧几里得算法。因为此过程中我们要进行多次的判断大数和小数,若小数的值比大数的要大,则需要交换着两个数,所以在此我们可以先封装一个交换两个×××的方法,把判断放在实现求取最大公约数的函数中,并不需要把判断野封装进去,这样可以尽量减小函数调用的次数,提高效率。
封装交换×××的代码如下:
void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; }
接下来需要考虑的就是实现辗转相除算法的代码了,通过解释,我们很容易就能写出来,代码如下:
int DetGreatestCommonDivisor(int max,int min)//辗转相除法 { while (max) { if (min > max) swap(&min, &max); max = max%min; } return min; }
2、更相减损法,又叫更相减损术,出自九章算法,其算法核心是首先两个数若存在偶数,则把偶数除2然后判断大小,用大数减小数,然后再重复以上操作,直到大数减小数为0时,这个小数或者大数就是它们的最大公约数。则“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。
其代码实现如下:
int GetGreatestCommonDivisor(int max, int min)//更相减损法 { while (max) { while (min % 2 == 0) { min /= 2; } while (max % 2 == 0) { max /= 2; } if (min > max) swap(&min, &max); max = max - min; } return min; }
如有不足还请指正