12

我们可以在 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(), ???);
4

4 回答 4

12

您可以使用指针算法来查找std::remove_if传递给谓词的特定元素的索引:

std::remove_if(data.begin(), data.end(),
               [&data](const double& d) { return (&d - &*data.begin()) % 2); });

请注意, remove_if 传递了取消引用迭代器的结果,这保证reference符合标准中的表 106 - 迭代器要求。

于 2014-04-17T02:22:09.863 回答
11

我实际上只为此做了一个帐户。使用 awesomeyi 答案。干净多了。

int count = 0;
auto final = std::remove_if (data.begin(), data.end(), [&count](const double d) {
    return (count++) % 2;
});

该标准确实说谓词是最后一次应用的 - 第一次。并且 remove_if 与 ForwardIterators 一起使用。

这意味着谓词仅以它们最初出现在序列中的相同顺序应用一次。

当然,除非库通过保留 ForwardIterator 的内部副本来欺骗您。

于 2014-09-17T01:19:44.790 回答
0

利用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

于 2014-04-17T00:39:15.253 回答
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;
}
于 2020-01-08T09:57:13.740 回答