web-dev-qa-db-ja.com

STLを使用してC ++で動作をマップ、フィルター、および削減する方法

Std :: transformを使用して、次のようにC++でマップの動作を複製できると思います。

std::vector<int> in = { 1 , 2 , 3 ,4 }; 
std::vector<int> out(in.size()); 

std::transform(in.being() , in.end() , out.begin() , [](const int & val)
{
    return val+1;
});

私はより良い方法はバックインサーターを使うことだと思います。

std::vector<int> out2;

std::transform(in.begin() , in.end() , std::back_inserter(out2) , [](const int & val){
      return val + 1;
});

// out will be { 2 , 3 ,4 ,5 }

私は正しいですか? STLを使用してC++でフィルターをかけ、操作を減らすにはどうすればよいですか?

16
nnrales

マッピングにはstd::transformを、フィルタリングにはstd::copy_ifを使用できます。

入力と、特定のタイプの実行モデルを使用するかどうかに応じて、reduceには2つのオプションがあります。一般的な使用例を示すために、以下の簡単な例をいくつか書きました。必要に応じて使用する必要があるこれらすべてのアルゴリズムには複数のオーバーロードがあることに注意してください。


  1. std::transform

整数のベクトルを二乗する:

std::vector<int> nums{1,2,3,4};
auto unary_op = [](int num) {return std::pow(num, 2);};
std::transform(nums.begin(), nums.end(), nums.begin(), unary_op);
// nums: 1, 4, 9, 16
  1. std::copy_if

整数のベクトルからのみ奇数をフィルタリングする:

std::vector<int> nums{1,2,3,4};
std::vector<int> odd_nums;
auto pred = [](int num) {return num & 1;};
std::copy_if(nums.begin(), nums.end(), std::back_inserter(odd_nums), pred);
// odd_nums: 1, 3
  1. std::reduce

並列実行モデルを使用して0から始まるベクトルの整数の合計。これは、たとえば、非常に大きなリストに対して削減操作を実行している場合に非常に役立ちます。この場合の二項演算子( "+")は連想的で可換であると考えてください。そうでない場合、動作は非決定的でした。これは本当に重要です。実行モデルがシーケンシャルでない場合、reduce操作は順不同です。 C++ 17以降でのみ使用できます。

std::vector<int> nums{1,2,3,4};
auto binary_op = [](int num1, int num2){return num1 + num2;};
int result = std::reduce(std::execution::par, nums.begin(), nums.end(), 0, binary_op);
// result: 10
  1. std::accumulate

実行モデルをサポートせず、reduce操作が順番に実行されることを除いて、reduceと同じです。

std::vector<int> nums{1,2,3,4};
auto binary_op = [](int num1, int num2){return num1 + num2;};
int result = std::accumulate(nums.begin(), nums.end(), 0, binary_op);
// result: 10
9
Sashank Aryal

使用するコンテナによって異なります。

std::back_inserterは、コンテナにPush_back関数がある場合にのみ機能します。

たとえば、back_insterterforward_listと一緒に使用することはできません。

その場合、同じようにstd::transformを呼び出す前にメモリを割り当てる必要があり、最初のアプローチの方が優れています。

0
Daksh