3

在 C++ 中,erase-remove 习惯用法是删除标准容器中满足给定条件的所有元素的好方法。

是否可以将擦除删除习惯用法扩展为一次在多个容器上工作?

也就是说,可以erase-remove在一个容器上调用类似的东西,并同时删除另一个容器中的相应元素吗?

在我的特殊情况下,容器std::vectors的大小都相同。

例如,如果从第一个容器中删除了元素0、、35,我也希望从第二个容器中删除元素0、、3和。5

例如,可以预先计算一个容器来标记要删除的元素,构建一个谓词来remove_if简单地索引到标志容器中,然后erase-remove多次调用。

是否可以在没有预先计算的情况下做我想做的事?

4

1 回答 1

-1

是的,你可以这样做。它按原样工作。我提供了一个示例代码并对其进行了解释。

// initialises a vector that holds the numbers from 0-9.
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  print(v);

  // removes all elements with the value 5
  v.erase( std::remove( v.begin(), v.end(), 5 ), v.end() ); 
  print(v); 

在这段代码中,我们想5从向量中删除,v然后使用std::removeand std::erase。您必须了解它的std::remove作用。std::remove交换容器中的元素,以使所有要删除的元素都到最后,并且此函数将迭代器返回到要删除的第一个元素。Nextstd::erase接受这个迭代器并删除从这个迭代器开始直到容器末尾的所有元素(实际上直到第二个参数。v.end()在我们的例子中)。

std::vector<int> v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> v2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };

auto removeIt=std::remove( v1.begin(), v1.end(), [](const int value){
    return value==0 || value==3 || value==5;
} );

// now v1 = { 1, 2, 4, 6, 7, 8, 9, 0, 3, 5 } and removeIt points to 0 element (next after 9)..
                     // removeIt = ^

std::erase(std::remove_if(v2.begin(),v2.end(),[&](const int value){
    // remove every object that can be found between removeIt and v1.end()
    return std::find(removeIt,v1.end(),value)!=v1.end();
}), v2.end());
// now v2 = { 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }
std::erase(removeIt,v1.end());
// now v1 = { 1, 2, 4, 6, 7, 8, 9 }

这段代码完全符合您的需要。

于 2016-02-20T04:28:08.377 回答