【问题标题】:GCD function in c++ sans cmath libraryC ++ sans cmath库中的GCD函数
【发布时间】:2012-06-12 23:12:57
【问题描述】:

我正在编写一个混合数字类,需要一个快速简单的“最大公约数”函数。谁能给我代码或代码链接?

【问题讨论】:

标签: c++ greatest-common-divisor


【解决方案1】:

libstdc++ 算法库有一个隐藏的 gcd 函数(我使用的是 g++ 4.6.3)。

#include <iostream>
#include <algorithm>

int main()
{
  cout << std::__gcd(100,24);
  return 0;
}

不客气:)

更新:正如@chema989 所指出的,在 C++17 中,std::gcd() 函数可用于 &lt;numeric&gt; 标头。

【讨论】:

  • 您不应依赖此类未记录的功能,因为它们可能会在库版本之间发生变化。
  • 它是否可用于 MSVC?
  • @vmrob:同意。您始终可以从 STL 复制实现。 Mbt925:完成。
  • 闻起来像作弊;)
【解决方案2】:

我很想投票结束 - 似乎很难相信很难找到实现,但谁知道呢。

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 &lt;numeric&gt; 并使用 std::gcd(如果您关心 gcd,那么您很有可能会对添加的 std::lcm 感兴趣)。

【讨论】:

  • 谢谢。我用谷歌搜索了 20 分钟,但没有得到任何明确的结果。
  • @JerryCoffin:为什么不直接做模板呢?
【解决方案3】:

快速递归版本:

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) 一些递归解决方案的问题在于,它们接近答案的速度太慢,以至于在到达那里之前往往会用完堆栈空间,例如考虑得很糟糕(伪-代码):

def sum (a:unsigned, b:unsigned):
    if b == 0: return a
    return sum (a + 1, b - 1)

你会发现像sum (1, 1000000000) 这样的东西非常昂贵,因为你(试图)使用了十亿左右的堆栈帧。递归的理想用例类似于二进制搜索,每次迭代将解决方案空间减少一半。最大公约数也是解决方案空间迅速减少的一个,因此对大量堆栈使用的担忧是没有根据的。

【讨论】:

  • +1 您甚至可以添加template&lt;class Integral&gt; 来替换int,在函数前添加一个constexpr 关键字,您就有了一个不错的编译时/运行时通用函数。
  • 第二种方法中可能存在拼写错误。应该return n1 吗?根据定义,此时 n2 将始终为零。
  • 很好,@Jim,解决了这个问题。
【解决方案4】:

对于 C++17,您可以使用在标头 &lt;numeric&gt; 中定义的 std::gcd

auto res = std::gcd(10, 20);

【讨论】:

    【解决方案5】:

    Euclidean 算法很容易用 C 语言编写。

    int gcd(int a, int b) {
      while (b != 0)  {
        int t = b;
        b = a % b;
        a = t;
      }
      return a;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      相关资源
      最近更新 更多