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

C++で階乗の桁数を数える方法をわかりやすく解説

本記事では、整数値が与えられたときに、まずその数の階乗を計算し、次にその結果に含まれる桁の総数を求める方法について解説します。

階乗とは何か

階乗とは、ある数から1ずつ減らしながらすべての値を掛け合わせて計算される数です。記号は「!」で表され、0!、1!、2!、3!、5!などのように書きます。なお、0!と1!は常に1となります。

例:2の階乗 = 2 × (2−1) = 2 × 1 = 2
  3の階乗 = 3 × (3−1) × (2−1) = 3 × 2 × 1 = 6

具体例

入力 − factorial(6)
出力 − factorial(6)の桁数:3

解説 − 6の階乗は720であり、3桁の数字で構成されているため、結果は3になります。

入力 − factorial(12)
出力 − factorial(12)の桁数:9

解説 − 12の階乗は479001600であり、9桁の数字で構成されているため、結果は9になります。

プログラムで使用するアプローチ

  • 階乗を計算したい数値を入力として受け取ります。

  • 数値が0未満の場合は0を返します。負の数には階乗が存在しないためです。

  • 数値が1以下の場合は1を返します。1!は1であり、桁数も1だからです。

  • 数値が2以上の場合は、2から始めて入力値以下である間繰り返すループを作成します。

  • ループの外側で一時変数(ここではdとします)を0で初期化し、ループ内では各反復ごとにlog10(i)の値を加算していきます。

  • 最後に、floor(d)+1 の値(小数点以下を切り捨てて1を足した値)を返します。

  • 結果を出力します。

サンプルコード

#include <iostream>
#include <cmath>
using namespace std;
// num! に含まれる桁数を返す関数
int count_digits(int num){
    // 階乗はnum >= 0のときのみ存在する
    if (num < 0){
       return 0;
    }
    // 基本ケース
    if (num <= 1){
       return 1;
    }
    // それ以外はnumまで反復して値を計算する
    double d = 0;
    for (int i=2; i<=num; i++){
       d += log10(i);
    }
    return floor(d) + 1;
}
int main(){
    cout<<"number of digits in factorial(1) is: "<<count_digits(1)<< endl;
    cout<<"number of digits in factorial(6) is: "<<count_digits(6) << endl;
    cout<<"number of digits in factorial(106) is: "<<count_digits(106) << endl;
    return 0;
}

実行結果

上記のコードを実行すると、次のような出力が生成されます。

number of digits in factorial(1) is: 1
number of digits in factorial(6) is: 3
number of digits in factorial(106) is: 171

まとめ

階乗の値は非常に大きくなるため、実際に掛け算を行って桁数を数えるのは非効率です。対数の性質「log(a×b) = log(a) + log(b)」を利用すれば、大きな数を直接計算することなく桁数を求められます。このテクニックは競技プログラミングなどでも役立つので、ぜひ覚えておきましょう。

  1. 【C++】長方形に含まれる正方形の総数を求めるアルゴリズムと実装

    縦の長さL、横の幅B(L≥B)の長方形が与えられたとします。この記事では、L×Bの長方形の中にいくつの正方形が含まれているかを効率的に求める方法を解説します。 上の図は3×2の長方形の例です。この長方形には、2×2の正方形が2個、1×1の正方形が6個含まれています。 合計:6+2=8個 規則性を見つける まず、正方形だけで構成されたB×Bの図形について考えてみましょう。 サイズL×Bの長方形には、必ずL×B個の1×1の正方形が含まれます。 含まれる最大の正方形のサイズはB×Bです。 L=B=1の場合:正方形の数=1 L=B=2の場合:正方形の数=1+4=5(2×2が1個、1×1が4個) L

  2. C++で数を割り切る桁の個数を求める方法

    問題の概要ある整数が与えられたとき、その数を割り切る桁(各桁の数字)の個数を数える問題です。例として、数が 1012 の場合を考えてみましょう。この場合、答えは 3 となります。1、1、2 の3つの桁がそれぞれ 1012 を割り切れるためです。解法のアプローチこの問題を解くには、剰余演算(% 演算子)を使って数の各桁を1つずつ取り出し、元の数がその桁の値で割り切れるかどうかを判定します。割り切れる場合はカウンターを1つ増やします。なお、桁が 0 の場合は 0 で割ることができないため、その桁はスキップ(無視)します。アルゴリズムの流れ元の数のコピーを作成し、0 になるまでループを繰り返します。