前言:对C++容器的操作(增删改查),我们需要掌握一些函数技巧,否则很容易使代码变得很冗长,效率低效。今天,我们来看看删除容器或字符串中的元素,如何使用erase()函数提高代码质量。
目录
一、字符串中的erase
假如我们有这样一个字符串:
cpp
string s = "hello world!";
- 如果你想删除world,如何操作?
cpp
s.erase(5); // 删除下标 5 直到到结尾 → "hello"
- 下面这行是什么意思呢?
cpp
s.erase(5, 6)
cpp
//解释:从下标 5 开始删 6 个元素 → "hello!"
- 删除某指定元素
cpp
s.erase(s.begin()+4); // 删除迭代器指向的字符
- 区间删除
cpp
s.erase(s.begin(), s.begin()+5); // 删除区间 [begin, begin+5)
特别需要注意的是 : s.erase(5) 只有一个参数时,是"删到结尾",不是"删 1 个"。
二、vector中的erase
假如我们有这样一个vector:
cpp
vector<int> v = {1, 2, 3, 4, 5};
- 删除某一个元素
cpp
v.erase(v.begin() + 2); // 删除 3 → {1,2,4,5}
- 区间删除
cpp
v.erase(v.begin(), v.begin() + 2); // 删除前 2 个 → {3,4,5}
- 循环中删除某元素
需要特别注意迭代器失效的情况:
陷阱:
cpp
//删除所有偶数
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it % 2 == 0) v.erase(it); // it 已失效,++it 是未定义行为
}
正确做法:
cpp
// 删除所有偶数
for (auto it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0) {
it = v.erase(it); // ✅ erase 返回下一个有效迭代器
} else {
++it;
}
}
- erase-remove组合
假如我们有这样一个vector:
cpp
vector<int> v = {1, 2, 3, 4, 5, 6};
如果要删除所有偶数:
cpp
// 删除所有偶数
v.erase(remove_if(v.begin(), v.end(),
[](int x){ return x % 2 == 0; }),
v.end());
上述删除逻辑解析:
bash
原数组: 1 2 3 4 5 6
remove_if 把奇数依次往前搬:
1 3 5 4 5 6
↑ ↑ └─ 新逻辑末尾(返回值指向这里)
└─────┘ 保留区
erase(新末尾, end) 把尾巴砍掉 → {1, 3, 5}
三、map中的erase
假如我们有这样一个map数据:
cpp
map<string,int> m = {{"a",1},{"b",3}};
- 按键删除
cpp
m.erase("b"); // 按键删
- 按迭代器删除
cpp
m.erase(m.begin()); // 按迭代器删