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

don*_*ton 8 c++ indexing iterator vector remove-if

我们可以在C++中使用remove_if来基于对元素进行操作的谓词在线性时间中从向量中移除元素.

bool condition(double d) {...}

vector<double> data = ...
std::remove_if (data.begin(), data.end(), condition);
Run Code Online (Sandbox Code Playgroud)

如果我的条件不依赖于价值,而是依赖指数怎么办?换句话说,如果我想删除所有奇数索引元素,或某些任意索引集等?

bool condition(int index) {//returns whether this index should be removed}

vector<double> data = ...
std::remove_if (data.begin(), data.end(), ???);
Run Code Online (Sandbox Code Playgroud)

Ton*_*roy 7

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

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

请注意,remove_if传递解除引用迭代器的结果,并且保证符合reference表106 - 标准中的迭代器要求.

  • 我不认为标准保证这将起作用,因为它假定在应用谓词之前不移动/交换元素.该标准仅保证谓词完全应用于"最后 - 第一"次.AFAICT实现可以在应用谓词之前移动/交换元素,这将是愚蠢的,但符合标准. (3认同)

小智 6

我实际上只为此创建了一个帐户.使用awesomeyi答案.方式更清洁.

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

该标准确实说谓语恰好是最后一次应用 - 第一次.remove_if与ForwardIterators一起使用.

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

除非当然,图书馆通过保留ForwardIterator的内部副本来控制你.