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

C++で自然数の約数をすべて効率的に求める方法

このチュートリアルでは、自然数の約数をすべて求めるプログラムをC++で作成します。一見単純な問題ですが、効率的なアルゴリズムを知っておくと、大きな数を扱う際に大きく役立ちます。それでは、解決の手順を見ていきましょう。

アルゴリズムの流れ

  • 対象となる数値を初期化します。
  • 1から与えられた数の平方根(√n)まで繰り返すループを作成します。
    • 与えられた数が現在の数で割り切れるかどうかを判定します。
    • 割り切れる場合は、現在の数と「与えられた数 ÷ 現在の数」の2つを出力します。

なぜ平方根までのループでよいのか?

約数は必ずペアで存在します。例えば n = 65 の場合、「1 × 65」「5 × 13」という組み合わせになります。小さい方の約数が必ず √n 以下になることを利用すれば、大きい方の約数(n ÷ i)も同時に求められます。この方法により、計算量は O(n) から O(√n) に削減され、大きな数でも高速に処理できます。

コード例

それでは、実際のコードを見てみましょう。

#include <bits/stdc++.h>
using namespace std;
void findDivisors(int n) {
    for (int i = 1; i <= sqrt(n); i++) {
        if (n % i == 0) {
            if (n / i == i) {
                cout << i << " ";
            }
            else {
                cout << i << " " << n / i << " ";
            }
        }
    }
    cout << endl;
}
int main() {
    findDivisors(65);
    return 0;
}

実行結果

上記のプログラムをコンパイルして実行すると、次の結果が得られます。

1 65 5 13

出力の解説

65の約数は「1, 5, 13, 65」の4つです。ループ内では i = 1 のとき「1 65」、i = 5 のとき「5 13」が出力されるため、結果は「1 65 5 13」の順に表示されます。約数を昇順に整理したい場合は、結果を一旦配列やベクターに格納してからソートするとよいでしょう。

まとめ

本チュートリアルでは、平方根を活用した効率的な約数の求め方を学びました。この手法は、素数判定や約数の個数を数える問題など、競技プログラミングや実務のさまざまな場面で応用できます。チュートリアルの内容について質問がある場合は、コメント欄でお気軽にお知らせください。

  1. C++で1〜nの範囲にあるすべての数の約数の個数を求める方法

    この問題では、整数Nが与えられ、1からnまでの範囲に含まれるすべての数について、それぞれの約数の個数を求めることが課題となります。問題の例具体例を見てみましょう。入力 : N = 7出力 : 1 2 2 3 2 4 2N = 7の場合、1の約数は「1」の1個、2の約数は「1, 2」の2個、3の約数は「1, 3」の2個、4の約数は「1, 2, 4」の3個…というように、各数の約数の個数を順に出力します。解法アプローチ1:各数ごとに約数を数える方法最もシンプルな解法は、1からNまでの各数に対して、実際に割り切れる数を順番にカウントしていく方法です。各数iについて、2からiまでの値で順に割りを試し、

  2. C++で集合の反射関係の数を求める方法

    この記事では、C++を使って集合上に定義できる反射関係(reflexive relation)の総数を求める方法について解説します。問題設定としては、整数 n が与えられたとき、n 個の自然数からなる集合上に存在する反射関係の個数を求めるというものです。 反射関係とは 集合 A 上の関係 R が反射的であるとは、「A に属するすべての要素 a に対して、順序対 (a, a) が必ず R に含まれる」という条件を満たすことを意味します。数式で表すと次のようになります。 (a, a) ∈ R (∀ a ∈ A) 具体的な入出力の例を見てみましょう。 入力 : x = 1 出力 : 1 説明 : 集