You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以子串匹配为条件调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:09:11