Root One

数学中心のブログです。

いろいろな方法で和を考える(C++)

今回は、プログラミング言語C++で、いろいろな方法で配列の和について考えていきたいと思います。

一番基本的な方法

まず、for文を用いて配列の和を計算します。

#include <iostream>
using namespace std;
int main()
{
	int a[] = { 1,2,3 };
	int sum = 0;
	for (int i = 0; i < 3; i++)
	{
		sum += a[i];
	}
	cout << sum << endl;
	return 0;
}
実行結果. 6 

上の例は単純ではありますが、次のように

end(a)-begin(a)

を用いて、配列のサイズを取得するほうが保守性の面で優れています。

#include <iostream>
using namespace std;
int main()
{
	int a[] = { 1,2,3 };
	int sum = 0;
	for (int i = 0; i < end(a)-begin(a); i++)
	{
		sum += a[i];
	}
	cout << sum << endl;
	return 0;
}

範囲for文を用いる方法

範囲for文を用いると、要素数の取得をする必要もありません。

#include <iostream>
using namespace std;
int main()
{
	int a[] = { 1,2,3 };
	int sum = 0;
	for (auto& e : a)
	{
		sum += e;
	}
	cout << sum << endl;
	return 0;
}
実行結果. 6 

範囲for文のautoの後の&記号はなくても良いですが、参照機能を使ったほうが、コピーを作らないので効率が良いはずです。

for_eachを用いる方法

ここからラムダ式を使っていきますので、少し難度が上がります。

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
	int a[] = { 1,2,3 };
	int sum = 0;
	for_each(begin(a), end(a), [&sum](int x)->void {sum += x; });
	cout << sum << endl;
	return 0;
}
実行結果. 6 

for_eachの第3引数のラムダ式の引数は、配列の要素を動きます。

accumulateを用いる方法

accumulateはC#でいえばAggregateに対応する関数です。
C#のAggregateについては、
https://shabonlearning.com/cSharp/linq4.html
で述べています。

#include <iostream>
#include <numeric>
using namespace std;

int main()
{
	int a[] = { 1,2,3 };
	int sum = accumulate(begin(a), end(a), 0, [](int x, int y)-> int {return x + y; });
	cout << sum << endl;
	return 0;
}
実行結果. 6 

上の例では、一般的な書き方をしましたが、和の場合は第4引数のラムダ式を省略することもできます。

少し脱線して、連分数の計算

accumulateの第4引数のラムダ式に分数関数を適用すると連分数の計算もできます。

#include <iostream>
#include <numeric>
using namespace std;

int main()
{
	double a[] = { 1,1,1 };
	double result = accumulate(begin(a), end(a), 1.0, [](double x, double y)-> double {return y + 1 / x; });
	cout << result << endl;
	return 0;
}
実行結果. 1.66667

このプログラムでは
 \displaystyle 1+\cfrac{1}{1+\cfrac{1}{1+\cfrac{1}{1}}}=\frac{5}{3}
という連分数を計算することになります。