C++で拡張ユークリッドの互除法を実装する方法
拡張ユークリッドの互除法(Extended Euclidean Algorithm)は、2つの整数の最大公約数(GCD)を求めるためのもう一つの手法です。通常のユークリッドの互除法と異なり、ベズーの等式 ax + by = gcd(a, b) を満たす係数 x と y を同時に求められる点が大きな特徴です。モジュラ逆数の計算などへの応用も可能で、コンピュータプログラムにおいて非常に効率的な手法として知られています。
アルゴリズムの流れ
拡張ユークリッドの互除法は、再帰呼び出しを利用して以下の手順で実装します。
開始
変数 a、b、x、y を宣言する
gcdExtended(int a, int b, int *x, int *y)
もし (a == 0) ならば
*x = 0;
*y = 1;
return b;
結果を格納するための2つの変数を用意する
再帰呼び出しの結果を使って x と y を更新する
終了
C++サンプルコード
#include <bits/stdc++.h>
using namespace std;
int gcdExtended(int a, int b, int *x, int *y) {
if (a == 0) {
*x = 0;
*y = 1;
return b;
}
int x1, y1;
int gcd = gcdExtended(b % a, a, &x1, &y1);
*x = y1 - (b / a) * x1;
*y = x1;
return gcd;
}
int main() {
int x, y;
int a = 35, b = 15;
cout << "gcd " << gcdExtended(a, b, &x, &y);
return 0;
}
実行結果
gcd 5
アルゴリズムの仕組み
このアルゴリズムのベースケースは a == 0 のときです。gcd(0, b) = b であり、0 × 0 + 1 × b = b が成り立つため、x = 0、y = 1 として b を返します。
再帰呼び出しから戻る際には、gcd(a, b) = gcd(b % a, a) という関係を利用します。b % a = b - (b / a) × a を代入して整理すると、次の更新式が導かれます。
*x = y1 - (b / a) * x1; *y = x1;
このプログラムでは a = 35、b = 15 としており、実行すると gcd(35, 15) = 5 が出力されます。このとき x = 1、y = -2 が求まり、35 × 1 + 15 × (-2) = 5 が実際に成り立つことが確認できます。
-
C++でバブルソートを実装する方法をわかりやすく解説
バブルソート(Bubble Sort)は、比較ベースの基本的なソートアルゴリズムの一つです。隣り合う要素同士を比較し、順序が正しくない場合は入れ替えることを繰り返すことで、データ全体を昇順(または降順)に整列させます。このアルゴリズムは他のソート手法と比べて実装が非常にシンプルであるという特徴がありますが、一方でいくつかの欠点も抱えています。特に大量のデータを扱う場合には処理に時間がかかるため、大規模なデータセットのソートには適していません。学習用や小規模データ向けのアルゴリズムとして理解しておくと良いでしょう。バブルソートの計算量時間計算量: 最良ケース O(n)、平均・最悪ケース O(n2
-
C++で基数ソート(ラディックスソート)を実装するプログラム
基数ソート(ラディックスソート)は、非比較型のソートアルゴリズムの一つです。要素同士を直接比較するのではなく、整数キーを構成する各桁に注目し、同じ桁位置・同じ値を持つ数字どうしをグループ化しながら並べ替えを行います。 「基数」とは記数法における底のことです。私たちが普段使う10進法では基数は10であるため、10進数を基数ソートで並べ替える際には、数値を一時的に格納するための10個のバケット(ポケット)が必要になります。 基数ソートの計算量 時間計算量: O(nk) ※nは要素数、kは最大桁数 空間計算量: O(n+k) 入力 − ソート前のデータ: 802 630 20 745 52 3