std::sort对std::string容器默认按字典序排序,因std::string的operator

std::sort 配合 std::string 默认就能字典序排序
只要容器里存的是 std::string,直接用 std::sort 就行,不用额外写比较函数——因为 std::string 的 operator 本身就是按字典序定义的。
常见错误是手动实现字符逐位比较,或者误以为要转成 ASCII 数值再比,反而绕远且易出错。
- 对
std::vector<:string></:string>排序:直接调用std::sort(v.begin(), v.end()) - 注意大小写敏感:
"Zoo"会排在"apple"前面(因为'Z'ASCII 是 90,'a'是 97,但字典序比较是逐字符比,首字符就决定了顺序) - 如果需要忽略大小写,得传自定义比较函数,不能靠默认行为
自定义比较函数处理大小写不敏感字典序
标准库不提供现成的 case-insensitive 字典序比较,必须自己写。核心是把每个字符转成小写(或大写)后再比,但要注意 locale 和非 ASCII 字符——简单项目用 std::tolower(需 <cctype></cctype>)即可,别直接减差值。
- 必须用
static_cast<unsigned char></unsigned>包裹参数传给std::tolower,否则遇到负 char 值(如 UTF-8 多字节中的高位字节)会 UB - 示例比较函数:
[](const std::string& a, const std::string& b) { for (size_t i = 0; i (a[i])); char cb = std::tolower(static_cast<unsigned char>(b[i])); if (ca != cb) return ca </unsigned> - 这个逻辑和
std::lexicographical_compare行为一致,但后者不能直接用于std::sort,得包一层
对 vector> 按 key 字典序排序
std::pair 的 operator 默认就是先比 <code>first,再比 second,所以如果 first 是 std::string,直接 std::sort 就按字典序排了 first,相同则按 second 升序。
- 不需要写比较函数,除非你想改变规则(比如只按
first比,second完全不参与) - 若只想按
first字典序、second无关,可写:[](const auto& x, const auto& y) { return x.first - 注意:如果
first是 C 风格字符串(const char*),operator 比的是指针值,不是内容——必须用 <code>std::strcmp或转std::string
std::map 和 std::set 默认就是字典序
只要 key 类型支持 operator(比如 <code>std::string),std::map 和 std::set 内部自动维护字典序——插入、遍历都是有序的,不用额外排序。
- 插入 1000 个字符串后直接 for-range 遍历,就是字典序输出
- 性能上,每次插入是 O(log n),比先插再
std::sort(O(n log n))更适合动态场景 - 但 map/set 不允许重复 key;如果原始数据有重复 string 且需要保留,就不能用它们替代 vector + sort
字典序本身不难,难的是边界:大小写、空字符串、嵌入 null 字符、UTF-8 多字节——日常用 ASCII 字符串时,std::sort 加 std::string 就够了;一旦涉及国际化或特殊输入,std::locale 或 ICU 库才真正派得上用场。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











