从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}
优雅的解决方案将不胜感激。
答案 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;
}));
如果您知道符合条件的元素大致数量,您可能需要考虑将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