将具有给定谓词的给定stl容器中的元素提取到另一个容器

时间:2016-11-26 22:05:31

标签: c++ stl

从STL容器中提取和移动符合特定条件的元素到另一个STL容器(例如vector)的最佳方法是什么。例如:

std::vector<int> original {1, 2, 6, 7, 9, 34, 9, 7, 3}

// For example, I only need event numbers
auto criteria = [](const int a) -> bool { return a%2 == 0? }

std::vector<int> newvec = ...;

所以,操作后我想要的是

original = {1, 7, 9, 9, 7, 3}
newvec = {2, 6, 34}

优雅的解决方案将不胜感激。

3 个答案:

答案 0 :(得分:4)

我选择自定义的删除/删除谓词,将删除的元素添加到newvec

original.erase(std::remove_if(original.begin(), original.end(), [&](int n){
    bool match = criteria(n);
    if(match){
        newvec.push_back(n);
    }
    return match;
}));

demo

如果您知道符合条件的元素大致数量,您可能需要考虑将vector<T>::reserve投入混合中。

答案 1 :(得分:1)

STL中没有这样的算法,但写的很短:

template <typename FIterator, typename OIterator, typename Pred>
FIterator splice_if( FIterator first, FIterator last, OIterator out, Pred p )
{
   FIterator result = first;
   for ( ; first != last; ++first ) {
       if ( p( *first ) ) {
           *result++ = *first;
       } else {
         *out++ = *first;
       }
   }
   return result;
}

答案 2 :(得分:1)

对于int类型的对象,使用移动迭代器没有多大意义,但在一般情况下,您可以使用移动迭代器。

这是一个演示程序,显示了任务的方法

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main() 
{
    std::vector<int> original {1, 2, 6, 7, 9, 34, 9, 7, 3};

    auto odd_value = []( int x ) { return x & 1; };

    auto n = std::count_if( original.begin(), original.end(), odd_value );

    std::vector<int> odd;
    odd.reserve( n );
    std::vector<int> even;
    even.reserve( original.size() - n );

    std::partition_copy( std::make_move_iterator( original.begin() ), 
                         std::make_move_iterator( original.end() ),
                         std::back_inserter( odd ),
                         std::back_inserter( even ),
                         odd_value );

    original = odd;

    for ( int x : original ) std::cout << x << ' ';
    std::cout << std::endl;

    for ( int x : even ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

它的输出是

1 7 9 9 7 3 
2 6 34