multiset::erase(key)删除所有匹配元素,erase(iterator)仅删单个;需用find()或lower_bound()获取迭代器再删除,注意迭代器失效问题。

multiset::erase(key) 会删光所有相同元素
这是最常踩的坑:multiset::erase(const key_type& key) 不是删一个,而是删掉所有匹配的元素。比如 ms.insert(5); ms.insert(5); ms.erase(5); 后,ms 就空了——不是只剩一个 5。
用迭代器 erase(it) 才能删单个
必须先拿到指向目标元素的迭代器,再传给 erase。常见做法是用 find() 或 lower_bound():
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
multiset<int> ms = {1, 3, 3, 3, 5};
auto it = ms.find(3); // 指向第一个 3
if (it != ms.end()) {
ms.erase(it); // 只删这一个,剩下两个 3
}</int>
-
find()最直观,但只适用于想删“某个值的任意一个出现” - 如果想删“第一个 ≥ x 的元素”,用
lower_bound(x)更合适 - 别用
erase(ms.begin())直接删头——虽然合法,但不明确意图,易误读
删特定位置的重复元素要小心迭代器失效
multiset 的 erase(iterator) 不会使其他迭代器失效(这点比 vector 友好),但要注意:删完后原 it 立即失效,不能再解引用或递增。
- 错误写法:
ms.erase(it); ++it;——it已无效,UB - 正确写法:删之前先保存下一个位置,如
auto next = std::next(it); ms.erase(it); it = next; - 批量删多个时,推荐用
while+find(),每次重新找,避免依赖旧迭代器
想删第 n 个重复元素?得手动遍历
multiset 不支持随机访问,没有 operator[]。要删“第三个 7”,只能从 begin() 开始数:
int target = 7;
int count = 0;
for (auto it = ms.begin(); it != ms.end(); ++it) {
if (*it == target && ++count == 3) {
ms.erase(it);
break;
}
}
- 时间复杂度 O(n),无法避免——这是
multiset的底层红黑树结构决定的 - 如果频繁按序号删重复元素,说明数据结构可能选错了,考虑
vector+ 排序,或加索引层
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










