2015-11-03 55 views
3

我有两个向量a和b具有相同的大小。移除向量元素使用向量中的条件<bool>

vector<int> a{ 4, 3, 1, 3, 1}; 
vector<bool> b{false,false,true,false,true}; 

我想删除的元素a如果b同一元素(相同指数)是真实的。

应用功能后:A = 4,3,3

注:我想用std算法或功能,而不是简单的for循环。

+0

你是用'std'而不是'for'循环表示什么意思? – Melebius

+2

使用像删除,转换等std算法,而不是我想象的原始循环。 – melak47

+0

@ melak47,正好! – user1436187

回答

6
std::vector<int> v {1,2,3,4,5,6}; 
    std::vector<bool> b {true, false, true, false, true, false}; 

    v.erase(std::remove_if(v.begin(), v.end(), 
     [&b, &v](int const &i) { return b.at(&i - v.data()); }), v.end()); 

LIVE DEMO

+1

问题被标记为C++ 11,所以没有通用的lambda表达式。并且使用更安全的擦除重载,如果所有元素都是“假”,这个将会崩溃。 –

+0

@GregorMcGregor公平的纠正。 – 101010

+0

永远不要在站起来调试http://coliru.stacked-crooked.com/a/2083debebfeb4718 –

4
void filter(std::vector<int>& v, const std::vector<bool>& b) 
{ 
    assert(v.size() == b.size()); 
    auto it = b.begin(); 
    v.erase(std::remove_if(v.begin(), v.end(), [&](int) { return *it++; }), v.end()); 
} 

Demo

+2

这取决于'remove_if'将谓词应用于元素的顺序,这是不能保证的。 –

1

我试图通过不使用lambda表达式,仅std功能推极限。我有两个解决方案,但它们都需要外部存储器:

首先解决

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

using namespace std; 

int main(int argc, char* argv[]) { 
    vector<int> a{4, 3, 1, 3, 1}; 
    vector<bool> b{true, false, true, false, true}; 
    vector<int> c; 
    vector<pair<int,bool>> tmp; 

    // Join                  
    transform(begin(a), end(a), 
      begin(b), 
      back_inserter(tmp), 
      make_pair<int const&,bool const&>); 

    // Filter                  
    auto last = partition(begin(tmp), end(tmp), 
         (bool const&(*)(std::pair<int,bool> const&)) 
         std::get<1,int,bool>); 

    // Copy back                 
    transform(begin(tmp), last, 
      back_inserter(c), 
      (int const&(*)(pair<int,bool> const&)) 
      get<0,int,bool>); 

    // Print (you could do a.swap(c) if you just want to modify 'a' 
    copy(begin(c), end(c), ostream_iterator<int>(cout, ", ")); 
    cout << endl; 
} 

解决方法二

它使用的valarray代替:

// 2nd solution using valarray             
    valarray<int> va(&a[0], a.size()); 
    valarray<bool> vb(b.size()); 
    copy(begin(b), end(b), begin(vb)); 

    valarray<int> vc(va[vb]); 
    copy(begin(vc), end(vc), ostream_iterator<int>(cout, ", ")); 
    cout << endl; 
0

没有一个STL算法,但修改后的版本为std::remove_if

template<class ForwardIt1, class ForwardIt2, class UnaryPredicate> 
ForwardIt1 remove_if_tagged(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, 
          UnaryPredicate p) 
{ 
    ForwardIt1 result = first1; 
    for (; first1 != last1; ++first1, ++first2) { 
     if (!p(*first1, *first2)) { 
      *result++ = *first1; 
     } 
    } 
    return result; 
} 

std::vector<int> a{ 4, 3, 1, 3, 1}; 
std::vector<bool> b{false,false,true,false,true}; 
a.erase(
    remove_if_tagged(
    a.begin(), a.end(), 
    b.begin(), 
    [](int, bool tag) { return tag; } 
), 
    a.end() 
);