erase-remove惯用法通过std::remove(或std::remove_if)将不满足条件的元素前移并返回新逻辑末尾迭代器,再调用容器的erase成员函数删除末尾无效元素,从而高效安全地移除序列容器中符合条件的元素。该方法适用于std::vector、std::deque和std::string等序列容器,因其连续或分块存储特性而效率较高;但不适用于关联容器,且在std::list上应优先使用其专用的remove_if成员函数以避免低效操作。

C++ STL中的
erase-remove
std::remove
std::remove_if
erase
要从C++ STL的序列容器(如
std::vector
std::deque
std::remove
std::remove_if
erase
std::remove
std::remove_if
std::remove
erase
std::remove
end()
erase
下面是一个简单的代码示例,演示如何移除
std::vector
3
#include <vector>
#include <algorithm> // 包含 std::remove 和 std::remove_if
#include <iostream> // 用于输出
int main() {
// 示例1: 移除所有值为3的元素
std::vector<int> numbers = {1, 2, 3, 4, 5, 3, 6, 7, 3, 8};
std::cout << "原始容器 (移除3): ";
for (int n : numbers) { std::cout << n << " "; }
std::cout << std::endl;
// 第一步: 逻辑移除。std::remove 将所有非3的元素前移。
// 它返回一个迭代器,指向第一个被“移除”的元素(即第一个3所在的新位置)。
auto new_end_iter = std::remove(numbers.begin(), numbers.end(), 3);
// 此时容器内部可能看起来像 {1, 2, 4, 5, 6, 7, 8, ?, ?, ?}
// new_end_iter 指向第一个问号的位置。
// 注意:容器的大小在这一步并没有改变。
// 第二步: 物理移除。使用 erase 成员函数删除从 new_end_iter 到 end() 的所有元素。
numbers.erase(new_end_iter, numbers.end());
std::cout << "移除3后: ";
for (int n : numbers) { std::cout << n << " "; }
std::cout << std::endl;
std::cout << "容器大小: " << numbers.size() << std::endl;
std::cout << "-----------------------------------" << std::endl;
// 示例2: 移除所有偶数 (使用 std::remove_if)
std::vector<int> another_numbers = {10, 21, 30, 41, 50, 61, 70, 81};
std::cout << "原始容器 (移除偶数): ";
for (int n : another_numbers) { std::cout << n << " "; }
std::cout << std::endl;
// 使用 lambda 表达式作为谓词,判断是否为偶数
auto new_end_iter_if = std::remove_if(another_numbers.begin(), another_numbers.end(),
[](int n){ return n % 2 == 0; });
another_numbers.erase(new_end_iter_if, another_numbers.end());
std::cout << "移除偶数后: ";
for (int n : another_numbers) { std::cout << n << " "; }
std::cout << std::endl;
std::cout << "容器大小: " << another_numbers.size() << std::endl;
return 0;
}std::remove
这其实是C++标准库设计哲学的一个体现,尤其是在算法和容器的分离上。
std::remove
std::remove_if
std::vector
std::list
立即学习“C++免费学习笔记(深入)”;
std::remove
std::remove
所以,如果你只调用
std::remove
capacity()
size()
erase
std::remove
end()
erase-remove
erase-remove
std::vector
std::deque
std::vector
erase-remove
std::vector
std::remove
memmove
vector::erase
std::vector
std::deque
std::deque
std::remove
std::deque
deque::erase
erase-remove
std::deque
std::string
std::string
std::vector<char>
erase-remove
std::string
std::list
std::list
erase-remove
std::list
std::remove
std::list::erase
std::list
list::remove
list::remove_if
std::list
对于关联容器(如
std::map
std::set
std::unordered_map
std::unordered_set
erase-remove
std::remove
erase
std::map
erase-remove
除了
erase-remove
容器的成员函数 remove
remove_if
std::list
std::forward_list
std::list
std::forward_list
remove(value)
remove_if(predicate)
std::list
std::forward_list
myList.remove(3);
myList.remove_if([](int n){ return n % 2 == 0; });关联容器的 erase
std::map
std::set
std::map
std::set
std::unordered_map
std::unordered_set
erase
erase
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
// 按键删除
myMap.erase(2);
// 遍历删除(安全做法)
for (auto it = myMap.begin(); it != myMap.end(); ) {
if (it->first % 2 != 0) { // 删除奇数键
it = myMap.erase(it); // erase 返回下一个有效迭代器
} else {
++it;
}
}std::unique
erase
std::unique
erase
std::unique
std::sort
std::unique
numbers.erase(std::unique(numbers.begin(), numbers.end()), numbers.end());
手动循环删除 (需要注意迭代器失效)
std::vector
std::deque
erase
erase
std::vector
erase-remove
// 这种方式效率较低,因为每次 erase 都可能导致大量元素移动
for (auto it = numbers.begin(); it != numbers.end(); ) {
if (*it == 3) {
it = numbers.erase(it); // erase 返回下一个有效迭代器
} else {
++it;
}
}对于
std::vector
std::deque
erase-remove
在选择删除策略时,始终优先考虑容器提供的成员函数(如
list::remove
map::erase
erase-remove
以上就是C++STL容器erase-remove惯用法解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号