exclusive_scanC++17

[機能]

  イテレータで指定された範囲の部分和(順番に和を求めながら,その段階までの和をその要素の値とする)を計算します.なお,inclusive_scan とは異なり,最後の要素は含まれず,また,生成される要素列の最初の要素は初期値に一致します.

[形式]
#include <numeric>

template <class InputIterator, class OutputIterator>
    OutputIterator exclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result, T init);
template <class InputIterator, class OutputIterator, class BinaryOperation>
    OutputIterator exclusive_scan(InputIterator first, InputIterator last,
                                  OutputIterator result, T init,
                                  BinaryOperation binary_op);		

[使用例]

  1. partial_sum,inclusive_scan,exclusive_scan,transform_inclusive_scan,transform_exclusive_scan の使用方法です.以下に示すプログラム例において,いくつかのコメント部分は,その上に記述された方法とほぼ同等なものであることを示しています(複数行の対応関係である場合もある).
    #include <stdio.h>
    #include <vector>
    #include <numeric>
    #include <algorithm>
    
    using namespace std;
    
    int max_v(int s, int n)
    {
    	return max(s, n);
    }
    
    int sum(int s, int n)
    {
    	return (n % 2 == 0) ? s + n : s;
    }
    
    int sum_a(int s, int n)
    {
    	return s + n;
    }
    
    int sq(int n)
    {
    	return n * n;
    }
    
    int main()
    {
    			// 初期設定
    	vector<int> v1 {1, 2, 3, 4, 5};
    	printf("v1 :");
    	for (auto x : v1)
    		printf("  %d", x);
    	printf("\n");
    			// v1 のすべての要素の部分和
    	printf("v1 のすべての要素の部分和(partial_sum)\n");
    	vector<int> v2(5);   // inserter を使用しない場合は,前もって大きさを指定
    	partial_sum(v1.begin(), v1.end(), v2.begin());
    //	vector<int> v2;
    //	partial_sum(v1.begin(), v1.end(), inserter(v2, v2.begin()));
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    			// v1 の偶数要素の部分和(partial_sum,最初は v1 の 1 番目の要素と必ず一致)
    	printf("v1 の偶数要素の部分和(partial_sum,最初は v1 の 1 番目の要素と必ず一致)\n");
    	partial_sum(v1.begin(), v1.end(), v2.begin(), sum);   // 関数
    //	partial_sum(v1.begin(), v1.end(), v2.begin(), [](int s, int n){ return (n % 2 == 0) ? s + n : s; });   // ラムダ式
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    			// v1 の n 番目の要素までの部分和(inclusive_scan)
    	printf("v1 の n 番目の要素までの部分和(inclusive_scan)\n");
    	inclusive_scan(v1.begin(), v1.end(), v2.begin());
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    			// v1 の 1 から n 番目の要素までの最大値(inclusive_scan)
    	printf("v1 の 1 から n 番目の要素までの最大値(inclusive_scan)\n");
    	inclusive_scan(v1.begin(), v1.end(), v2.begin(), [](int a, int b) { return max(a, b); });
    //	inclusive_scan(v1.begin(), v1.end(), v2.begin(), max_v);
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    
    	inclusive_scan(v1.begin(), v1.end(), v2.begin(), [](int a, int b) { return max(a, b); }, 10);
    //	inclusive_scan(v1.begin(), v1.end(), v2.begin(), max_v, 10);
    	printf("  v2(初期値を10にした場合) :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    			// v1 の 1 から n-1 番目の要素までの最大値(exclusive_scan)
    	printf("v1 の 1 から n-1 番目の要素までの最大値(exclusive_scan)\n");
    	exclusive_scan(v1.begin(), v1.end(), v2.begin(), 0, [](int a, int b) { return max(a, b); });
    //	exclusive_scan(v1.begin(), v1.end(), v2.begin(), 0, max_v);
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    			// v1 の 1 から n 番目の要素までの 2 乗の和(transform_inclusive_scan)
    	printf("v1 の 1 から n 番目の要素までの 2 乗の和(transform_inclusive_scan)\n");
    	transform_inclusive_scan(v1.begin(), v1.end(), v2.begin(), [](int a, int b){ return a + b; }, [](int x){ return x * x; });
    //	transform_inclusive_scan(v1.begin(), v1.end(), v2.begin(), plus<>(), sq);   // 二項関数オブジェクト plus
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    			// v1 の 1 から n-1 番目の要素までの 2 乗の和(transform_exclusive_scan)
    	printf("v1 の 1 から n-1 番目の要素までの 2 乗の和(transform_exclusive_scan)\n");
    	transform_exclusive_scan(v1.begin(), v1.end(), v2.begin(), 0, [](int a, int b){ return a + b; }, [](int x){ return x * x; });
    //	transform_exclusive_scan(v1.begin(), v1.end(), v2.begin(), 0, sum_a, sq);
    	printf("  v2 :");
    	for (auto x : v2)
    		printf("  %d", x);
    	printf("\n");
    
    	return 0;
    }
    			
    (出力)
    v1 :  1  2  3  4  5
    v1 のすべての要素の部分和(partial_sum)
      v2 :  1  3  6  10  15
    v1 の偶数要素の部分和(partial_sum,最初は v1 の 1 番目の要素と必ず一致)
      v2 :  1  3  3  7  7
    v1 の n 番目の要素までの部分和(inclusive_scan)
      v2 :  1  3  6  10  15
    v1 の 1 から n 番目の要素までの最大値(inclusive_scan)
      v2 :  1  2  3  4  5
      v2(初期値を10にした場合) :  10  10  10  10  10
    v1 の 1 から n-1 番目の要素までの最大値(exclusive_scan)
      v2 :  0  1  2  3  4
    v1 の 1 から n 番目の要素までの 2 乗の和(transform_inclusive_scan)
      v2 :  1  5  14  30  55
    v1 の 1 から n-1 番目の要素までの 2 乗の和(transform_exclusive_scan)
      v2 :  0  1  5  14  30
    			
[参照]

inclusive_scanpartial_sumtransform_inclusive_scantransform_exclusive_scan

菅沼ホーム 本文目次 演習問題解答例 付録目次 索引