您的删除-擦除代码不正确。remove-erase 习惯用法如下所示:
vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it, v.end());
在这种情况下,它具有擦除所有等于 5 的值的效果,但它最大限度地减少了实现该目标所需的复制量。
您的查找擦除代码仅删除等于 5 的第一个值,因此它可以执行您想要的操作。
您的 remove-erase 代码将所有不等于 5 的值移动到向量的前面(就是这样std::remove
做的),擦除向量的剩余元素之一,并在之后留下任何剩余的元素具有未指定的值(这也是remove
做)。如果向量不包含 a5
开头,则它具有未定义的行为,因为在这种情况下remove
会返回v.end()
。
因此,如果您只想擦除几个等于 5 的单个元素,那么std::remove
对您来说没有用,因为它不会保留(其他)5。如果您想将非 5 值移到开头,将 5 值移到末尾,然后再删除 5 中的第一个,那么实际上您可以使用std::partition
not with 来执行此操作std::remove
:
auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.erase(it);
虽然,由于一个 5 与另一个一样好,因此您可以通过擦除最后一个 5 而不是第一个来获得相同的结果,并且当有多个 5 时效率更高:
auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.pop_back();
如果你能以某种方式确定向量最初包含一个等于 5 的元素(不多或少),那么你的两位代码会做同样的事情。在那种情况下,您不需要it != v.end()
在查找擦除代码中进行测试,您会知道它不相等。你可以这样做v.erase(find(v.begin(), v.end(), 5))
。