删除元素的算法

cod*_*der 4 c++ algorithm

我知道c ++有擦除删除习惯用法.并且该remove方法<algorithm>将目标元素移动到范围的后面.

但是,下面的输出对我来说很困惑.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> vec = {10, 20, 30, 20, 30, 20, 10, 10, 20};

    auto pend = remove(vec.begin(), vec.end(), 20);
    cout << "After removing 20: " << endl;
    for (const auto& x : vec) {
        cout << x << " ";
    }
    cout << endl;

    cout << "use pend: " << endl;
    for (auto p = vec.begin(); p != pend; p++) {
        cout << " " << *p;
    }

    cout << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

After removing 20:
10 30 30 10 10 20 10 10 20
use pend:
10 30 30 10 10
Run Code Online (Sandbox Code Playgroud)

这里有两个问题:

  1. 对于"去除20后",为什么有10个混合20后面?10 30 30 10 10 20 10 10 20

  2. 对于"使用pend:",为什么它不能打印最后两个10?原始矢量中有5个10,不应该删除10个?

从库中,remove()方法返回迭代器pend

模板ForwardIterator删除(ForwardIterator first,ForwardIterator last,const T&val); 未删除的最后一个元素后面的元素的迭代器.first和this迭代器之间的范围包括序列中不比较等于val的所有元素.

rom*_*m1v 13

从阵列:

10 20 30 20 30 20 10 10 20
Run Code Online (Sandbox Code Playgroud)

当你删除所有20,你希望得到:

10 30 30 10 10
Run Code Online (Sandbox Code Playgroud)

std::remove只是移动项目,它允许剩余的值未指定:

指向新逻辑端和范围的物理端之间的元素的迭代器仍然是可解除引用的,但元素本身具有未指定的值

所以你得到:

10 30 30 10 10 xx xx xx xx
               ^
               pend
Run Code Online (Sandbox Code Playgroud)

这解释了你的结果.

如果您需要删除项目,请致电vec.erase(pend, vec.end()):

调用remove之后通常会调用容器的erase方法,该方法会擦除未指定的值并减小容器的物理大小以匹配其新的逻辑大小.