Page List

Search on the blog

2010年11月20日土曜日

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

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

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

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

では、早速コードと実行結果を。
  1. #include<numeric>  
  2.   
  3. #define INF 999999999  
  4.   
  5. int x[] = {1,2,3,4,5,6,7,8,9,10};  
  6. int y[] = {15, 12, 99, 27};  
  7. int z[] = {10, 20, 150, 100};  
  8. int w[] = {1,3,10,100, -12, 2, 4};  
  9.   
  10. int multiply(int x, int y) {  
  11.     return x*y;  
  12. }  
  13.   
  14. int gcd(int a, int b) {  
  15.     if (!b)  
  16.         return a;  
  17.     return gcd(b, a%b);  
  18. }  
  19.   
  20. int lcd(int a, int b) {  
  21.     return a*b/gcd(a,b);  
  22. }  
  23.   
  24. int myMin(int a, int b) {  
  25.     return (a < b) ?  a : b;  
  26. }  
  27.   
  28. int myMax(int a, int b) {  
  29.     return (a > b) ? a : b;  
  30. }  
  31.   
  32. int main() {  
  33.     cout << accumulate(x, x+SIZE(x), 0) << endl;  
  34.     cout << accumulate(x, x+SIZE(x), 1, multiply) << endl;  
  35.     cout << accumulate(y, y+SIZE(y), *y, gcd) << endl;  
  36.     cout << accumulate(z, z+SIZE(z), *z, lcd) << endl;  
  37.     cout << accumulate(w, w+SIZE(w), INF, myMin) << endl;  
  38.     cout << accumulate(w, w+SIZE(w), -INF, myMax) << endl;  
  39.   
  40.     return 0;  
  41. }  

[実行結果]
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 件のコメント:

コメントを投稿