C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で有理数の最小公倍数(LCM)を求める方法

本記事では、有理数(分数)の最小公倍数(LCM)を求める方法を解説します。例えば、{2/7, 3/14, 5/3} という有理数のリストが与えられた場合、そのLCMは 30/1 となります。

有理数のLCMを求める公式

この問題を解くには、まずすべての分子のLCM(最小公倍数)を計算し、次にすべての分母のGCD(最大公約数)を計算します。有理数のLCMは、次の式で表されます。

$$LCM = \frac{すべての分子のLCM}{すべての分母のGCD}$$

各分数の倍数となる有理数は、分子がすべての分子の公倍数であり、かつ分母がすべての分母の公約数である必要があります。その中で最小のものが「分子のLCM ÷ 分母のGCD」になるというわけです。

C++による実装例

以下は、このアルゴリズムをC++で実装したサンプルコードです。分数は pair<int, int>(分子, 分母)として扱っています。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 最大公約数を使って最小公倍数を求める
int LCM(int a, int b) {
    return (a * b) / (__gcd(a, b));
}

// すべての分子のLCMを計算する
int numeratorLCM(vector<pair<int, int> > vect) {
    int result = vect[0].first;
    for (int i = 1; i < vect.size(); i++)
        result = LCM(vect[i].first, result);
    return result;
}

// すべての分母のGCDを計算する
int denominatorGCD(vector<pair<int, int> vect) {
    int res = vect[0].second;
    for (int i = 1; i < vect.size(); i++)
        res = __gcd(vect[i].second, res);
    return res;
}

// 有理数のLCMを表示する
void rationalLCM(vector<pair<int, int> > vect) {
    cout << numeratorLCM(vect) << "/" << denominatorGCD(vect);
}

int main() {
    vector<pair<int, int> > vect;
    vect.push_back(make_pair(2, 7));
    vect.push_back(make_pair(3, 14));
    vect.push_back(make_pair(5, 3));
    cout << "有理数のLCM: ";
    rationalLCM(vect);
}

実行結果

有理数のLCM: 30/1

コードの解説

プログラムの処理の流れは以下の通りです。

  1. LCM関数:2つの整数の最小公倍数を「a × b ÷ GCD(a, b)」で求めます。GCC拡張の __gcd() を利用しています。
  2. numeratorLCM関数:ベクターに格納されたすべての分数の分子(first)に対して、先頭から順にLCMを畳み込んで計算します。
  3. denominatorGCD関数:すべての分母(second)に対して、先頭から順にGCDを畳み込んで計算します。
  4. rationalLCM関数:分子のLCMと分母のGCDを組み合わせ、「分子のLCM / 分母のGCD」の形式で結果を出力します。

検算してみましょう。分子 2, 3, 5 のLCMは 30、分母 7, 14, 3 のGCDは 1 となるため、答えは 30/1 となり、実行結果と一致します。

計算量と注意点

n個の有理数を処理する場合、各要素ごとにGCD計算(ユークリッドの互除法)を行うため、全体の時間計算量は O(n log M) となります(M は扱う数値の最大値)。ただし、LCMの計算では分子同士の積が大きくなりやすいため、大きな数を扱う場合は long long 型の使用やオーバーフロー対策を検討してください。また、__gcd() はGCC固有の関数のため、移植性を重視する場合はC++17で標準化された std::gcd() を使うとよいでしょう。

  1. C++のCHAR_BITとは?意味と使い方を解説

    CHAR_BITは、char型が持つビット数を表すマクロです。C++では「limits.h」ヘッダーファイル(C++では<climits>)で宣言されており、一般的な環境では1バイトが8ビットであることを示します。このマクロを利用することで、移植性の高いコードを書くことができます。環境に依存せずにchar型のビット数を取得できるため、ビット演算やデータサイズの計算に役立ちます。CHAR_BITの使用例以下は、C++でCHAR_BITを使用したサンプルコードです。CHAR_BITとsizeofを組み合わせてint型の全ビット数を求め、整数値を2進数形式で出力しています。#includ

  2. C++で最小公倍数(LCM)を求めるプログラム:初心者向けに2つの方法を解説

    最小公倍数(LCM: Least Common Multiple)とは、2つの整数に共通する倍数の中で最も小さい数のことです。プログラミングの基礎的なアルゴリズム学習においても頻出のテーマであり、C++を使えば簡単に求めることができます。最小公倍数とは?具体例で確認例として、15と9という2つの数を考えてみましょう。それぞれ素因数分解すると次のようになります。15 = 5 × 3 9 = 3 × 3この場合、15と9の両方を割り切れる最小の数、つまり最小公倍数は 45 となります。方法1:大きい方の数から順に増やしていく方法まず紹介するのは、最も直感的なアプローチです。2つの数のうち大きい方