Page List

Search on the blog

2010年11月20日土曜日

C++で関数型プログラミング:accumulate編

マルチパラダイム言語として知られるC++。

競技系プログラミングばかりやっていると、手続き型でばかり書いてしまう。
職場では、ぱっと見オブジェクト指向のようなスパゲッティソースを保守している。。

最近、C++で関数型プログラミングっぽいこともできることを発見。
今日は「畳み込み関数」をC++でやってみます。
畳み込み関数は、Pythonでいうreduce()です。。

では、早速コードと実行結果を。

#include<numeric>

#define INF 999999999

int x[] = {1,2,3,4,5,6,7,8,9,10};
int y[] = {15, 12, 99, 27};
int z[] = {10, 20, 150, 100};
int w[] = {1,3,10,100, -12, 2, 4};

int multiply(int x, int y) {
return x*y;
}

int gcd(int a, int b) {
if (!b)
return a;
return gcd(b, a%b);
}

int lcd(int a, int b) {
return a*b/gcd(a,b);
}

int myMin(int a, int b) {
return (a < b) ? a : b;
}

int myMax(int a, int b) {
return (a > b) ? a : b;
}

int main() {
cout << accumulate(x, x+SIZE(x), 0) << endl;
cout << accumulate(x, x+SIZE(x), 1, multiply) << endl;
cout << accumulate(y, y+SIZE(y), *y, gcd) << endl;
cout << accumulate(z, z+SIZE(z), *z, lcd) << endl;
cout << accumulate(w, w+SIZE(w), INF, myMin) << endl;
cout << accumulate(w, w+SIZE(w), -INF, myMax) << endl;

return 0;
}

[実行結果]
55
3628800
3
300
-12
100

accumulate()のシグネチャーはこんな感じ。
T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op );
  1. input は畳み込み対象の開始位置
  2. lastは畳み込み対象の終了位置
  3. initは初期値
  4. binary_opは引数を2つもつ関数のポインタ
です。第4引数を省略すると、operator+()が畳み込み関数として使用されます。
注意ポイントは、accumulate()を使用する場合は、numericをincludeしないといけないという点です。algorithmではないので間違えないように!!

やばいぞ、C++。C++好き度が上がりました。。

0 件のコメント:

コメントを投稿