使用remove_if从C ++向量中删除索引

时间:2014-04-17 00:28:56

标签: c++ vector indexing iterator remove-if

我们可以在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 个答案:

答案 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适用于Forw​​ardIterators。

这意味着谓词只按照它们最初在序列中出现的顺序应用一次。

除非当然,图书馆通过保留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;
}