如何以子串匹配为条件调用unordered_set::erase删除元素
在std::unordered_set中删除符合子串匹配条件的元素
现有cplusplus.com上的
std::unordered_set::erase示例代码,仅支持精确匹配删除元素(比如删除"France")。我在项目中使用std::unordered_set<std::string>,需要修改代码实现删除所有符合子串匹配条件的元素(例如首字符为'F'的元素),想知道能不能通过遍历迭代器、判断元素的子串条件后调用erase来实现?
原示例代码:
// unordered_set::erase #include <iostream> #include <string> #include <unordered_set> int main () { std::unordered_set<std::string> myset = {"USA","Canada","France","UK","Japan","Germany","Italy"}; myset.erase ( myset.begin() ); // erasing by iterator myset.erase ( "France" ); // erasing by key myset.erase ( myset.find("Japan"), myset.end() ); // erasing by range std::cout << "myset contains:"; for ( const std::string& x: myset ) std::cout << " " << x; std::cout << std::endl; return 0; }
当然可以通过迭代器判断条件来删除,但要注意unordered_set的迭代器在元素被删除后会失效,不能用普通的遍历写法(比如范围for或for (auto it = begin(); it != end(); ++it)),否则会触发未定义行为。
正确的做法是利用erase的返回值——它会返回指向被删除元素下一个有效元素的迭代器,以此安全遍历整个容器:
#include <iostream> #include <string> #include <unordered_set> int main () { std::unordered_set<std::string> myset = {"USA","Canada","France","UK","Japan","Germany","Italy","Finland"}; // 删除所有首字符为'F'的元素 auto it = myset.begin(); while (it != myset.end()) { if (!it->empty() && (*it)[0] == 'F') { // erase返回下一个有效迭代器,无需手动++ it = myset.erase(it); } else { ++it; } } std::cout << "myset contains:"; for ( const std::string& x: myset ) std::cout << " " << x; std::cout << std::endl; return 0; }
核心注意事项:
- 不能在调用
erase(it)后直接执行++it,因为erase会让当前迭代器失效,后续的++it操作非法。 - 利用
erase的返回值更新迭代器,是unordered_set及其他关联容器中安全删除元素的标准方式。 - 示例中的判断条件是首字符为'F',你可以根据需求修改为任意子串匹配逻辑,比如判断元素是否包含指定子串:
if (it->find("substring") != std::string::npos)。
内容的提问来源于stack exchange,提问作者Robert Holmén
相关产品推荐
相关产品推荐

