web-dev-qa-db-ja.com

C ++ sans cmathライブラリのGCD関数

私は混合数値クラスを書いており、素早く簡単な「最大公約数」関数が必要です。誰でも私にコードまたはコードへのリンクを教えてもらえますか?

24
Connor Black

私は閉会に投票したいと思います-実装を見つけるのは難しいと信じるのは難しいようですが、誰が確実に知っています。

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について気にするなら、std::lcmそれも追加されました)。

38
Jerry Coffin

Libstdc ++アルゴリズムライブラリには非表示のgcd関数があります(g ++ 4.6.3を使用しています)。

_#include <iostream>
#include <algorithm>

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

どういたしまして :)

更新:@ chema989が指摘したように、C++ 17には_<numeric>_ヘッダーで使用可能なstd::gcd()関数があります。

51

クイック再帰バージョン:

_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クラスのような非基本型を使用している場合)。

この関数は、実際には 私の以前の回答 からのものでしたが、画面サイズの積分アスペクト比を計算するためのものでしたが、元のソースは私がずっと前に学んだユークリッドアルゴリズムでした ここWikipediaで その背後にある数学を知りたい場合。


(a) いくつかの再帰的な解決策の問題は、非常によく考えられていない(擬似コード)など、そこに到達する前にスタックスペースが不足する傾向があるため、答えにゆっくりと近づくことです。

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

sum (1, 1000000000)のようなものでは、10億個程度のスタックフレームを使用しようとすると非常に高価になります。再帰の理想的なユースケースは、バイナリ検索のようなもので、反復ごとに解空間を半分に減らします。最大の共通の除数は、ソリューションのスペースが急速に減少するため、大量のスタックの使用に対する懸念はそこにありません。

19
paxdiablo

C++ 17の場合、ヘッダーstd::gcdで定義されている<numeric>を使用できます。

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

ユークリッド アルゴリズムはCで書くのは非常に簡単です。

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