std::numeric



numeric

numericにはコンテナに対する数値的な操作を行う4つの関数が定義されている.

#include <numeric>

総和(accumulate)

template <class InputIterator, class T> 
  T accumulate(InputIterator first, InputIterator last, T init);
template <class InputIterator, class T, class BinaryOperation> 
  T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);

範囲[first, last)内の値の総和を計算する.initは初期値. 和以外のオペレーションを行いたい場合は,2つめの定義でbinary_opを指定する.

コード例

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
 
int mul(int x, int y)
{
    return x*y;
}
 
int main(void)
{
    vector<int> a;
    a.resize(10);
    int b[10];
    
    for(int i = 0; i < 10; ++i){
        a[i] = i;
        b[i] = i+1;
    }
 
    cout << "a : ";
    for(int i = 0; i < 10; ++i) cout << a[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "b : ";
    for(int i = 0; i < 10; ++i) cout << b[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    int result1 = accumulate(a.begin(), a.end(), 0);
    int result2 = accumulate(b, b+10, 1, mul);
    
    cout << result1 << endl;
    cout << result2 << endl;
 
    return 0;
}

実行結果

a : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
b : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
45
3628800

要素間差分(adjacent_difference)

template <class InputIterator, class OutputIterator> 
  OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);
template <class InputIterator, class OutputIterator, class BinaryOperation>
  OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);

範囲[first, last)の各要素間の差を計算して,resultに格納する.要素の値を

x[0], x[1], x[2], ... 

とするとresultには

x[0], x[1]-x[0], x[2]-x[1], ...

が格納される. 差以外のオペレーションを行いたい場合は,2つめの定義でbinary_opを指定する.

コード例

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
 
int add(int x, int y)
{
    return x+y;
}
 
int main(void)
{
    vector<int> a;
    a.resize(10);
    int b[10];
    
    for(int i = 0; i < 10; ++i){
        a[i] = i;
        b[i] = i;
    }
 
    cout << "a : ";
    for(int i = 0; i < 10; ++i) cout << a[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "b : ";
    for(int i = 0; i < 10; ++i) cout << b[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    vector<int> result1;
    result1.resize(10);
    int result2[10];
    adjacent_difference(a.begin(), a.end(), result1.begin());
    adjacent_difference(b, b+10, result2, add);
    
    cout << "a : ";
    for(int i = 0; i < 10; ++i) cout << result1[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "b : ";
    for(int i = 0; i < 10; ++i) cout << result2[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    return 0;
}

実行結果

a : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
b : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
a : 0, 1, 1, 1, 1, 1, 1, 1, 1, 1
b : 0, 1, 3, 5, 7, 9, 11, 13, 15, 17

内積(inner_product)

template <class InputIterator1, class InputIterator2, class T>
  T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
  T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init,
                    BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);

first1, first2で指定されたコンテナの各要素の積の総和(要するに内積)を計算して返す.initは初期値. デフォルトは和と積の組み合わせだが,2つめの定義でbinary_op1, binary_op2を指定することで任意のオペレータを適用できる. この場合関数内では,

while(first! != last1) init = binary_op1(init, binary_op2(*first1++, *first2++));

のように計算される(デフォルトは,init = init+(*first1++)*(*first2++)).

コード例

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
 
int add(int x, int y)
{
    return x+y;
}
 
int main(void)
{
    vector<int> a;
    a.resize(10);
    int b[10], c[10];
    
    for(int i = 0; i < 10; ++i){
        a[i] = i;
        b[i] = i+1;
        c[i] = 10-i;
    }
 
    cout << "a : ";
    for(int i = 0; i < 10; ++i) cout << a[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "b : ";
    for(int i = 0; i < 10; ++i) cout << b[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "c : ";
    for(int i = 0; i < 10; ++i) cout << c[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    int result1 = inner_product(a.begin(), a.end(), a.begin(), 0);
    int result2 = inner_product(b, b+10, c, 0, add, add);
    
    cout << result1 << endl;
    cout << result2 << endl;
 
    return 0;
}

実行結果

a : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
b : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
c : 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
285
110

Prefix Sum(partial_sum)

template <class InputIterator, class OutputIterator> 
  OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result);
template <class InputIterator, class OutputIterator, class BinaryOperation> 
  OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op);

範囲[first, last)内の要素のpartial sum (もしくはprefix sum, scanなどとも呼ばれる)を計算する.要素の値を

x[0], x[1], x[2], ... 

とするとresultには

x[0], x[0]+x[1], x[0]+x[1]+x[2], ...

が格納される. binary_opを指定することで和以外のオペレーションも行える.

コード例

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
 
int mul(int x, int y)
{
    return x*y;
}
 
int main(void)
{
    vector<int> a;
    a.resize(10);
    int b[10];
    
    for(int i = 0; i < 10; ++i){
        a[i] = 1;
        b[i] = i+1;
    }
 
    cout << "a : ";
    for(int i = 0; i < 10; ++i) cout << a[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "b : ";
    for(int i = 0; i < 10; ++i) cout << b[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    vector<int> result1;
    result1.resize(10);
    int result2[10];
    partial_sum(a.begin(), a.end(), result1.begin());
    partial_sum(b, b+10, result2, mul);
    
    cout << "a : ";
    for(int i = 0; i < 10; ++i) cout << result1[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    cout << "b : ";
    for(int i = 0; i < 10; ++i) cout << result2[i] << (i == 9 ? "" : ", ");
    cout << endl;
 
    return 0;
}

実行結果

a : 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
b : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
a : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
b : 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-11-30 (水) 13:48:10