我们可以在C ++中使用remove_if,根据对元素进行操作的谓词,以线性时间从向量中删除元素。
bool condition(double d) {...}
vector<double> data = ...
std::remove_if (data.begin(), data.end(), condition);
如果我的条件不依赖于值,而是依赖于指数,该怎么办?换句话说,如果我想删除所有奇数索引元素,或某些任意索引集等?
bool condition(int index) {//returns whether this index should be removed}
vector<double> data = ...
std::remove_if (data.begin(), data.end(), ???);
答案 0 :(得分:6)
您可以使用指针算法查找std::remove_if
传递给谓词的特定元素的索引:
std::remove_if(data.begin(), data.end(),
[](const double& d) { return (&d - &*data.begin()) % 2); });
请注意,remove_if传递取消引用迭代器的结果,并且根据表106 - 标准中的迭代器要求保证为reference
。
答案 1 :(得分:6)
我实际上只为此创建了一个帐户。使用awesomeyi答案。更干净。
int count = 0;
auto final = std::remove_if (data.begin(), data.end(), [&count](const double d) {
return (count++) % 2;
});
标准确实说谓词最后一次应用 - 第一次。 remove_if适用于ForwardIterators。
这意味着谓词只按照它们最初在序列中出现的顺序应用一次。
除非当然,图书馆通过保留ForwardIterator的内部副本来控制你。
答案 2 :(得分:1)
利用lambas
可以捕获变量的事实。一个简单的例子:
vector<double> data = {5, 3, 6, 7, 8};
int count = 0;
auto final = std::remove_if (data.begin(), data.end(), [&](const double d) {
bool b = false;
if(count % 2) b = true;
++count;
return b;
});
for(auto beg = data.begin(); beg != final; ++beg)
cout << *beg << endl;
代码将打印:5 6 8
答案 3 :(得分:0)
与 std::remove_if
类似的算法,但将索引传递给谓词
template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_indexes_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
ForwardIt dest = first;
for(ForwardIt i = first; i != last; ++i)
if (!p(std::distance(first, i)))
*dest++ = std::move(*i);
return dest;
}