c++如何使用set容器去重_c++ set自动排序与去重特性【入门】

1次阅读

std::set天然去重并升序排序,重复insert()静默失败且返回pair.second为false;降序需显式指定std::greater;自定义比较器时find/count必须遵循相同逻辑。

c++如何使用set容器去重_c++ set自动排序与去重特性【入门】

std::setc++ 中天然支持去重和升序排序,无需额外逻辑 —— 但前提是元素类型满足可比较(operator 或自定义比较器),且你没误用 <code>std::multiset 或手动插入重复值。

为什么插入重复元素后 size 没变?

这是 std::set 的正常行为:它只保留唯一值,重复 insert() 调用会静默失败(返回 std::pair<iterator bool></iterator> 中的 false)。常见误判是只看返回值不检查 second 字段:

std::set<int> s; auto res = s.insert(5);  // res.second == true res = s.insert(5);       // res.second == false → 此时 size 仍为 1
  • 别依赖 s.size() 变化来判断是否新增成功,应检查 insert() 返回值的 second
  • 若需批量去重并保持原始顺序,std::set 不适用 —— 改用 std::unordered_set + std::vector 记录顺序
  • std::set 插入复杂度是 O(log n),高频插入场景注意性能瓶颈

如何让 set 按降序排列?

默认使用 std::less<t></t>(即 ),要降序只需换比较器:<code>std::greater<t></t>

std::set<int, std::greater<int>> desc_set; desc_set.insert({3, 1, 4, 1, 5});  // 实际存为 {5,4,3,1}
  • 比较器类型必须在模板参数中显式写出,不能运行时切换
  • 自定义类型需提供对应比较逻辑:要么重载 operator>,要么传入 Lambda(C++20 起支持,但需用 std::set<t decltype></t> 形式)
  • 若仅需一次排序输出,用 std::vector + std::sort 更灵活;std::set 的排序是“持续维护”的开销

字符串去重时大小写敏感怎么办?

std::set<:String></:string> 默认按字典序区分大小写("Apple""apple")。若需忽略大小写去重,不能直接用默认比较器:

立即学习C++免费学习笔记(深入)”;

  • 方案一:插入前统一转小写(std::transform + std::tolower),但丢失原始大小写形式
  • 方案二:自定义比较器,内部做 case-insensitive 比较(注意 locale 安全,简单 ASCII 场景可用 std::tolower
  • 方案三:用 std::unordered_set 配合哈希策略,更高效但无序 —— 若只要去重不要排序,这是更优解

真正容易被忽略的是:一旦用了自定义比较器,find()count() 等操作必须保证传入的 key 满足相同比较逻辑,否则查不到 —— 比如大小写不敏感比较器下,用 "HELLO"find("hello") 才有效,反之亦然。

text=ZqhQzanResources