std::set天然去重并升序排序,重复insert()静默失败且返回pair.second为false;降序需显式指定std::greater;自定义比较器时find/count必须遵循相同逻辑。
在 C++ 中天然支持去重和升序排序,无需额外逻辑 —— 但前提是元素类型满足可比较(
或自定义比较器),且你没误用
或手动插入重复值。
为什么插入重复元素后 size 没变?
这是
的正常行为:它只保留唯一值,重复
调用会静默失败(返回
中的
)。常见误判是只看返回值不检查
字段:
别依赖
变化来判断是否新增成功,应检查
返回值的
若需批量去重并保持原始顺序,
不适用 —— 改用
+
记录顺序
插入复杂度是
,高频插入场景注意性能瓶颈
如何让 set 按降序排列?
默认使用
(即
),要降序只需换比较器:
:
比较器类型必须在模板参数中显式写出,不能运行时切换
自定义类型需提供对应比较逻辑:要么重载
,要么传入 lambda(C++20 起支持,但需用
形式)
若仅需一次排序输出,用
+
更灵活;
的排序是“持续维护”的开销
字符串去重时大小写敏感怎么办?
默认按字典序区分大小写(
≠
)。若需忽略大小写去重,不能直接用默认比较器:
C知道
CSDN推出的一款AI技术问答工具
下载
立即学习
“
C++免费学习笔记(深入)
”;
方案一:插入前统一转小写(
+
),但丢失原始大小写形式
方案二:自定义比较器,内部做 case-insensitive 比较(注意 locale 安全,简单 ASCII 场景可用
)
方案三:用
配合哈希策略,更高效但无序 —— 若只要去重不要排序,这是更优解
真正容易被忽略的是:一旦用了自定义比较器,
、
等操作必须保证传入的 key 满足相同比较逻辑,否则查不到 —— 比如大小写不敏感比较器下,用
去
才有效,反之亦然。
std::setoperator<std::multisetstd::setinsert()std::pairfalsesecondstd::set s;
auto res = s.insert(5); // res.second == true
res = s.insert(5); // res.second == false → 此时 size 仍为 1
s.size()insert()secondstd::setstd::unordered_setstd::vectorstd::setO(log n)std::less<std::greaterstd::set> desc_set;
desc_set.insert({3, 1, 4, 1, 5}); // 实际存为 {5,4,3,1}
operator>std::setstd::vectorstd::sortstd::setstd::set"Apple""apple"std::transformstd::tolowerstd::tolowerstd::unordered_setfind()count()"HELLO"find("hello")