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

C++の再帰を活用してln(N!)の値を求める方法

はじめに

数値Nが与えられたとき、再帰(リカージョン)を用いてln(N!)の値を求める方法を解説します。ここでいうln()とは、自然対数、すなわち底がe(ネイピア数)の対数のことです。

解法の考え方

この問題は、対数の基本的な性質を利用することでシンプルに解くことができます。階乗の対数は、積の対数を対数の和に変換できる性質により、次のように展開できます。

$$\ln\lgroup N!\rgroup=\ln\lgroup N*\lgroup N-1\rgroup *\lgroup N-2\rgroup *\dotsm*2*1\rgroup=\ln\lgroup N\rgroup+\ln\lgroup N-1\rgroup+\dotsm+\ln\lgroup 1\rgroup$$

つまり、ln(N!)は「1からNまでの各整数の対数の総和」と等しくなります。これを再帰の形で表すと、次の漸化式が成り立ちます。

ln(N!) = ln(N) + ln((N-1)!)

再帰の終了条件は「Nが1以下になったとき」です。この場合、ln(1) = 0 であるため、0を返します。

C++での実装例

#include<iostream>
#include<cmath>
using namespace std;
double factLog(int n) {
    if (n <= 1)
        return 0;
    return factLog(n - 1) + log(n);
}
int main() {
    int N = 3;
    cout << factLog(N);
}

実行結果

1.79176

コードの解説

factLog関数は、引数nが1以下の場合に0を返すことで再帰を終了します。それ以外の場合は、factLog(n - 1)の戻り値にlog(n)を加算した値を返します。これにより、ln(1) + ln(2) + ... + ln(N)が再帰的に順番に計算されていきます。

例えばN = 3の場合、ln(3!) = ln(6) = ln(2) + ln(3) ≈ 0.6931 + 1.0986 ≈ 1.79176 となり、実行結果と一致します。

まとめ

対数の性質「積の対数は対数の和に等しい」を利用することで、大きな階乗の値を直接計算せずにln(N!)を効率よく求められます。再帰を使った実装はコードが簡潔で、数学的な定義とも対応が分かりやすいのが特徴です。

  1. C++で列車の停車駅の組み合わせ数を求める方法

    地点XとYの間にはn個の中間駅があるとします。ここで、「どの2つの停車駅も隣り合わない」という条件のもとで、s個の駅に停車する列車の配置方法が何通りあるかを求める問題を考えてみましょう。この記事では、停車駅の組み合わせ数を求めるためのアプローチを段階的に詳しく解説します。この問題は、本質的には組合せ論の問題であり、s個の停車駅の選び方の総数を求めることになります。 問題を解くアプローチ まず具体例として、中間駅が8個あり、そのうち3個の駅に停車させたい場合を考えてみます。 n = 8, s = 3 このとき、列車が停車できない駅は(n − s)、つまり5個残ることになります。 停車できない

  2. C++で楕円の面積を求めるプログラムの作成方法

    この記事では、C++を使って楕円(だえん)の面積を求める方法を解説します。楕円にはいくつかの重要な構成要素があり、それぞれの意味を理解しておくと計算の仕組みがより明確になります。楕円の主な構成要素要素説明中心楕円の中心点。2つの焦点を結ぶ線分の中点でもあります。長軸楕円における最も長い直径です。短軸楕円における最も短い直径です。弦楕円上の2点を結ぶ線分のことです。焦点楕円を定義する2つの特別な点。図中に示された2点が該当します。通径焦点を通り、長軸に対して垂直な直線(線分)のことです。楕円の面積の公式楕円の面積は、長半径 a と短半径 b を使って次の式で表されます。面積 = π × a ×