C++で級数 1+(1+3)+(1+3+5)+…+(1+3+5+…+(2n−1)) の総和を求める方法
この問題では、整数 n が与えられ、級数 1 + (1+3) + (1+3+5) + (1+3+5+7) + … + (1+3+5+7+…+(2n−1)) の総和を求めるプログラムを作成します。
問題例
入力: n = 5
出力: 55
つまり、ユーザーから数値「n」を受け取り、この級数の総和を計算して出力するのが課題です。
まず、この級数がどのような構造になっているのかを確認しましょう。
- n = 1 のとき、級数は「1」になります。
- n = 2 のとき、最終項の 2n−1 は 2×2−1 = 3 となるため、級数は「1 + (1+3)」になります。
| n の値 | 2n−1 | 級数の形 |
| 1 | 1 | 1 |
| 2 | 3 | 1 + (1+3) |
| 3 | 5 | 1 + (1+3) + (1+3+5) |
| 4 | 7 | 1 + (1+3) + (1+3+5) + (1+3+5+7) |
解法のアプローチ
この問題には大きく分けて2つの解き方があります。1つは数学的な解法で、総和を表す式を導出できればループ処理が不要になります。もう1つは、プログラム内で二重ループを使う方法です。
方法1:ループを使った直接的な解法
この級数は、各項自体がさらに級数になっているという特徴があります。そこで、ネストされたループ(二重ループ)を使用します。外側のループで第何項まで処理するかを制御し、内側のループで各項の値を計算します。
コード例
#include<stdio.h>
int calcSum(int n){
int sum = 0;
for (int i = 1; i <= n; i++) {
// 各項の最初の値は必ず 1
int value = 1;
for (int j = 1; j <= i; j++) {
sum += value;
// 次の奇数へ
value += 2;
}
}
return sum;
}
int main(){
int n = 35;
printf("%d までの級数の総和は %d です", n , calcSum(n));
}
出力
35 までの級数の総和は 14910 です
プログラムの動作解説
ここでは n = 2 を入力した場合を例に、処理の流れを追ってみましょう。
- ユーザーが n の値(例:2)を入力します。
- 初期値 0 の変数「sum」が宣言されます。
- i = 1 のとき、条件 i <= n が真のため外側のループが実行されます。
- 変数 value の値は 1 です。
- j = 1 のとき、j と i が等しいため条件が真となり、内側のループが動作します。
- value の値が sum に加算され、sum は 0 + 1 = 1 になります。
- value に 2 が加算され、新しい値は 1 + 2 = 3 になります。
- j が 1 増えて 2 になると、j > i となるため内側のループを抜けます。
- 次に i が 1 増えて 2 になり、条件 i <= n が真のため再びループに入ります。
- 変数 value は再び 1 で初期化されます。
- j = 1 のとき、1 < 2 なのでループが実行されます。
- value が sum に加算され、sum は 1 + 1 = 2 になります。
- value に 2 が加算され、新しい値は 1 + 2 = 3 になります。
- j が 1 増えて 2 になります。j と i が等しいので条件は真であり、ループは継続します。
- value が sum に加算され、sum は 2 + 3 = 5 になります。
- value に 2 が加算され、新しい値は 3 + 2 = 5 になります。
- j が 1 増えて 3 になると、j > i となるためループを抜けます。
- さらに i が 3 になると、条件 i <= n が偽になるため外側のループを終了します。
- メッセージと sum の値が画面に出力されます。
方法2:数学的な解法
コードを書く前に数学的な解法を見つけておくと、コードを大幅にシンプルにできます。
まず、級数の一般項 Tn について考えてみましょう。重要なポイントとして、連続する奇数の級数 1 + 3 + 5 + 7 + 9 + … + (2n−1) の総和は n2 になることが知られています。つまり、今回求める総和 S は次のように書けます。
S = 12 + 22 + 32 + … + n2
これは「平方数の和」の公式を使えば、次のような閉じた形で表せます。
S = n(n + 1)(2n + 1) / 6
この公式を使えば、ループ処理なしに定数時間 O(1) で答えを求められます。
数学的解法のコード例
#include<stdio.h>
int calcSum(int n){
// 求める総和
return (( (n) * (n + 1) * (2*n + 1 ) )/6 ) ;
}
int main(){
int n = 35;
printf("%d までの級数の総和は %d です", n , calcSum(n));
}
出力
35 までの級数の総和は 14910 です
上記コードの動作:
例えば、ユーザーが n = 2 を入力した場合、2n−1 の値は 3 となり、級数は 1 + (1+3) になります。コードを通じて総和がどのように得られるか見てみましょう。
- 引数 2 を渡して calcSum() 関数が呼び出されます。
- 関数内で公式 n(n+1)(2n+1)/6 に基づいて総和(この場合は 5)が計算され、main 関数に返されます。
- 答えを含むメッセージが画面に出力されます。
-
C++で等差数列(算術級数)の和を求めるプログラム
初項「a」、公差「d」、項数「n」が与えられたとき、等差数列を生成し、その合計を計算するのが本プログラムの目的です。 等差数列(算術級数)とは 等差数列とは、隣り合う項の差が常に一定である数列のことです。数列の初項は「a」に固定され、項と項の間の共通の差(公差)は「d」で表されます。 数列は次のように表されます。 a, a + d, a + 2d, a + 3d, … 入力例と出力例 入力: a = 1.5, d = 0.5, n = 10 出力: 等差数列の合計は: 37.5 入力: a = 2.5, d = 1.5, n = 20 出力: 等差数列の合計は: 335 解き方のアプローチ
-
C++のconstキーワードとは?定数宣言の基本とメリットを解説
C++におけるconstは、変数を「定数」として宣言するための型修飾子です。const付きで宣言された変数は、一度初期化するとその値を後から変更することができません。 constを使うメリット constを使用する最大の利点は、プログラム内で値が意図せず書き換えられるのを防げることです。例えば、円周率(PI)のような不変の値を扱う場合、プログラムのどの部分からもその値が変更されないようにしたいはずです。このような値はconstとして宣言しておくことで、誤った代入から守ることができます。 コンパイラの最適化との関係 const修飾された型を持つオブジェクトは、コンパイラによって読み取り専用メ