accumulate関数

http://www.geocities.jp/ky_webid/cpp/library/023.html

数値演算のアルゴリズムをいくつか勉強したいと思います。これらはalgorithmヘッダではなく、numericヘッダに定義されています。

まずはaccumulate関数について勉強します。

これは指定された範囲内のデータに対して+演算子を適応させるだけの関数です。

実装例を見てみましょう。

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

int main () {
    vector<int> data;
    
    for(int i=0;i<10;++i) {
        data.push_back(i);
    }
    
    int sum = accumulate(data.begin(),data.end(),0);
    
    cout << sum << endl;
    
    return 0;
}
$ main
45

できました。第三引数に0というのを渡していますが、これは初期値になります。また、戻り値とこの初期値の型が一致していないとダメなので注意が必要です。

さてこの関数、何が便利なのかというと、同等の処理を書こうとした場合for文でループしながら+演算子で足していくことになります。

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

int main () {
    vector<int> data;
    
    for(int i=0;i<10;++i) {
        data.push_back(i);
    }
    
    int sum = 0;
    size_t size=data.size();
    for(size_t i=0;i<size;++i ) {
        sum += data[i];
    }
    
    cout << sum << endl;
    
    return 0;
}
$ main
45

コードが長い上に、例えばこの合計値をそのまま別の関数に渡したい場合にも面倒です。

accumulateなら

func( accumulate(data.begin(),data.end(),0) );

といったようにそのまま別の関数へ渡せるので処理がスッキリしますね。

また単純に+演算子を呼ぶだけなのでオーバーロードされたクラスでもバッチリ動いてくれます。

以下はstringクラスを使った例です。

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

int main () {
    vector<string> data;
    
    data.push_back("aaa");
    data.push_back("bbb");
    data.push_back("ccc");
    
    string str = accumulate(data.begin(),data.end(),string());
    
    cout << str << endl;
    
    return 0;
}
$ main
aaabbbccc

うまく連結されていますね。