2つの数のk番目の公約数を求めるアルゴリズムとC言語での実装方法
プログラミングの定番問題の一つに、「2つの整数 x と y が与えられたとき、それらに共通する約数(公約数)のうち、小さい方から数えて k 番目の値を出力する」というものがあります。この記事では、その考え方と具体的な実装方法をわかりやすく解説します。
問題の例
たとえば x = 9、y = 18、k = 2 が入力として与えられた場合を考えてみましょう。
9 の約数 : 1, 3, 9
18 の約数 : 1, 2, 3, 6, 9, 18
公約数 : 1, 3, 9
→ 2番目の公約数は「3」
このように、まず両方の数の約数を確認し、共通して現れる値を小さい順に並べれば、k番目の公約数が求まります。なお、最も大きい公約数は最大公約数(GCD)と一致します。
アルゴリズム
効率的に求めるための基本的な手順は以下の通りです。
- x と y のうち小さい方の値を num とする(公約数は必ず num 以下になるため)
- i を 1 から num まで順番に調べる
- x を i で割った余りが 0 で、かつ y を i で割った余りも 0 であれば、i は公約数なのでカウントを 1 増やす
- カウントが k に達した時点の i が答えとなる
- ループが終了しても見つからなければ、k番目の公約数は存在しない(例:-1 を返す)
C言語による実装例
#include <stdio.h>
int main(void) {
int x = 9, y = 18, k = 2; // 2つの数と、求めたい公約数の順位 k
int num, count = 0;
// 小さい方の値を num に設定
if (x < y)
num = x;
else
num = y;
// 1 から num まで順に公約数かどうかを判定
for (int i = 1; i <= num; i++) {
if (x % i == 0 && y % i == 0) { // 両方で割り切れたら公約数
count++;
if (count == k) {
printf("%d番目の公約数は %d です\n", k, i);
return 0;
}
}
}
printf("%d番目の公約数は存在しません\n", k);
return -1;
}
実行結果
上記のプログラムを実行すると、次のような出力が得られます。
2番目の公約数は 3 です
計算量のポイント
この手法では、小さい方の数を N としたとき、ループを最大 N 回回すため計算量は O(N) となります。数がそれほど大きくなければ十分実用的ですが、より大きな数を扱う場合は、ユークリッドの互除法で最大公約数を求め、その約数を列挙する方法の方が効率的です。
-
C言語で非平方数(完全平方数以外の数)を出力する方法
プログラムの概要ある数の「平方」とは、その数にその数自身を掛け合わせた値のことです。「平方数」または「完全平方数」とは、ある整数を二乗することで得られる整数を指します。完全平方数は自然数を二乗した数であり、具体的には以下のような数になります。1, 4, 9, 16, 25, 36, 49, 64, 81, 100以下は、1から100までの各完全平方数とその平方根の一覧です。√1 = 1 (12 = 1 であるため) √4 = 2 (22 = 4 であるため) √9 = 3 (32 = 9 であるため) √16 = 4 (42 = 16 であるため) √25 = 5 (52 = 25 であるため
-
Pythonで2つの数の公約数を求めるプログラムの書き方
はじめに この記事では、以下の問題文に対する解決方法について学んでいきます。 問題文 2つの整数が与えられたとき、それらに共通する約数(公約数)の個数を表示する必要があります。 アプローチの考え方 まず、入力として受け取った2つの数のうち、小さい方の値(最小値)を計算します。続いて、1からその最小値までの各値で2つの数を順番に割っていき、両方の数を割り切ることができるかどうかをループ処理で確認します。 条件が真(True)と評価されるたびに、カウンターを1ずつ増加させます。最終的なカウンターの値が、2つの数の公約数の個数となります。 実装例 それでは、以下のコードで実際の実装を見てみましょう。