删除矢量元素使用矢量<bool>中的条件

Remove vector element use the condition in vector<bool>

本文关键字:gt 条件 bool 元素 删除 lt      更新时间:2023-10-16

我有两个大小相同的向量a和b。

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

如果b中的相同元素(相同索引)为真,我想删除a中的元素。

应用函数后:a=4,3,3

注意:我想使用std算法或函数,而不是简单的for循环。

  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());

现场演示

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());
}

演示

我试图通过不使用lambdas,只使用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;

没有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()
);