我正在编写一个混合数字类,需要一个快速简单的“最大公约数”函数。任何人都可以给我代码或代码的链接?
答案 0 :(得分:51)
libstdc ++算法库有一个隐藏的gcd函数(我使用的是g ++ 4.6.3)。
#include <iostream>
#include <algorithm>
int main()
{
cout << std::__gcd(100,24);
return 0;
}
欢迎你:)
更新:正如@ chema989所指出的那样,在C ++ 17中,std::gcd()
标题可以使用<numeric>
函数。
答案 1 :(得分:38)
我很想投票结束 - 似乎很难相信实施很难找到,但谁知道肯定。
template <typename Number>
Number GCD(Number u, Number v) {
while (v != 0) {
Number r = u % v;
u = v;
v = r;
}
return u;
}
在C ++ 17或更新版本中,您可以#include <numeric>
,并使用std::gcd
(如果您关心gcd,那么您很可能对{{1}感兴趣也被添加了。)
答案 2 :(得分:18)
快速递归版本:
unsigned int gcd (unsigned int n1, unsigned int n2) {
return (n2 == 0) ? n1 : gcd (n2, n1 % n2);
}
或等效的迭代版本,如果你强烈反对递归(a):
unsigned int gcd (unsigned int n1, unsigned int n2) {
unsigned int tmp;
while (n2 != 0) {
tmp = n1;
n1 = n2;
n2 = tmp % n2;
}
return n1;
}
只需替换您自己的数据类型,零比较,赋值和模数方法(例如,如果您使用某些非基本类型,例如bignum
类)。
此函数实际上来自earlier answer of mine,用于计算屏幕尺寸的积分宽高比,但原始来源是我很久以前学过的欧几里德算法,详细here on Wikipedia如果你想知道数学背后。
(a)一些递归解决方案的问题在于它们接近答案的速度很慢,在到达目的地之前,你往往会耗尽堆栈空间,例如非常糟糕的想法(伪-code):
def sum (a:unsigned, b:unsigned):
if b == 0: return a
return sum (a + 1, b - 1)
你会发现sum (1, 1000000000)
之类的东西非常昂贵,因为你(尝试)使用了大约十亿个堆叠帧。递归的理想用例类似于二进制搜索,您可以在每次迭代时将解决方案空间减少一半。最大的公约除数也是解决方案空间迅速减少的因素,因此对大量堆栈使用的担忧在那里是没有根据的。
答案 3 :(得分:7)
对于C ++ 17,您可以使用标题std::gcd
中定义的<numeric>
:
auto res = std::gcd(10, 20);
答案 4 :(得分:5)
使用C语言编写Euclidean算法非常容易。
int gcd(int a, int b) {
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}