在C编程中排序是一个核心任务。std::sort来自algorithm是一个极其强大的“神奇黑盒”可以为你排序vector。vectorint nums {50, 10, 30};std::sort(nums.begin(), nums.end());-nums变成{10, 30, 50}(从小到大)。vectorstring names {Charlie, Alice};std::sort(names.begin(), names.end());-names变成{Alice, Charlie}(按字母顺序)。但是如果你有一堆“日期”字符串呢vectorstring dates {10-12-2023, 05-01-2024};如果你“天真地”调用std::sortstd::sort(dates.begin(), dates.end());结果会是{05-01-2024, 10-12-2023}。这是错误的2024年的日期排在了2023年的前面一个简单的比喻“字典” vs “日历”默认std::sort(用于字符串)就像一个“字典”。它只懂“字母顺序”。在“字典”里0(以 ‘0’ 开头)确实排在1(以 ‘1’ 开头) 的前面。你想要的日期排序就像一个“日历”。你需要一种“智能”排序它能理解Year(年),Month(月),Day(日) 的逻辑关系。解决方案我们不能直接排序字符串。我们必须“教会” C 如何“阅读”日期。最好的方法是创建一个“自定义盒子”struct把日期拆分成“年”、“月”、“日”三个整数。“教会”std::sort我们的“日历规则”。我们必须提供一个“自定义比较器”Comparator函数告诉std::sort“先比较年份如果年份相同再比较月份…”在本教程中你将学会为什么不能直接排日期字符串“字典” vs “日历”。如何使用struct来“打包”日期数据 (Y, M, D)。“黄金法则”如何编写一个“自定义比较器”函数 (Comparator)。std::sort的“第三个参数”如何把你的“规则”传递给std::sort。实战演练编写一个完整的sortDates程序。“X光透 视”用调试器“亲眼目睹”std::sort是如何“调用”你的“自定义规则”的。前置知识说明 (100% 自洽)变量 (Variable)理解存储数据的“盒子”如int year 2024;。vector(向量)C标准库提供的一种“动态数组”“魔法弹性盒子列表”。你需要#include vector。struct(结构体)一种“蓝图”用于创建“自定义盒子”把相关数据如y,m,d打包在一起。#include algorithmstd::sort“神奇黑盒”所在的“工具包”。bool函数一个返回true(真) 或false(假) 的函数我们将用它来编写“规则”。if/else if/else用于编写“规则”的逻辑判断。编译 (Compile)C代码“食谱”必须被“编译”“烘焙”才能变成电脑可执行的程序“蛋糕”。第一部分“自定义盒子”——Date结构体首先我们“设计”一个“蓝图”告诉C一个Date对象长什么样。12345678910111213#include iostream#include vector#include algorithm // 包含 std::sort#include stringusingnamespacestd;// “蓝图”一个自定义的 Date 盒子// 它把日期“拆分”成三个 *可比较* 的整数structDate {intday;intmonth;intyear;};现在我们可以创建Date对象的vector而不是string的vectorvectorDate calendar { {10, 12, 2023}, {5, 1, 2024}, {15, 12, 2023} };第二部分“日历规则”——自定义比较器std::sort的“默认规则”是operator(小于号)。我们现在要提供一个新的“规则手册”一个函数来代替。比较器 (Comparator) 的“黄金法则”std::sort需要一个函数bool compare(A, B)。如果你希望A排在B的前面你的函数必须返回true。如果你希望A排在B的后面或相同你的函数必须返回false。compareDates.cpp(“日历规则”函数)1234567891011121314151617181920212223242526// “规则手册”告诉 std::sort 如何比较两个 Date 对象boolcompareDates(constDate a,constDate b) {// 规则 1先比较“年”if(a.year b.year) {returntrue;// a 的年份小a 应该排在前面}if(a.year b.year) {returnfalse;// a 的年份大a 应该排在后面}// “行内预警”如果程序运行到这里说明 a.year b.year// 规则 2如果年份相同再比较“月”if(a.month b.month) {returntrue;// a 的月份小a 应该排在前面}if(a.month b.month) {returnfalse;// a 的月份大a 应该排在后面}// “行内预警”如果程序运行到这里说明年份和月份都相同// 规则 3如果月份相同最后比较“日”return(a.day b.day);// 如果 a.day 小返回 true}第三部分“实战演练”——结合sort与“规则”现在我们把std::sort和我们的“规则手册”compareDates结合起来。date_sort.cpp(完整代码)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354#include iostream#include vector#include algorithm#include stringusingnamespacestd;// --- 1. “蓝图” ---structDate {intday;intmonth;intyear;};// --- 2. “规则手册” ---boolcompareDates(constDate a,constDate b) {if(a.year b.year)returntrue;if(a.year b.year)returnfalse;// 年份相同if(a.month b.month)returntrue;if(a.month b.month)returnfalse;// 月份也相同return(a.day b.day);}// 辅助函数打印日期voidprintDates(conststring title,constvectorDate dates) {cout title endl;for(constauto d : dates) {// (为了美观我们补 0)printf( %02d-%02d-%04d\n, d.day, d.month, d.year);}}intmain() {// 3. 创建“自定义盒子”列表vectorDate calendar {{10, 12, 2023},// 10-Dec-2023{5, 1, 2024},// 05-Jan-2024{15, 12, 2023},// 15-Dec-2023{2, 2, 2023}// 02-Feb-2023};printDates(--- 原始顺序 ---, calendar);// 4. “按下按钮”并“递上纸条” (规则手册)std::sort(calendar.begin(), calendar.end(), compareDates);printDates(\n--- 日历排序后 ---, calendar);return0;}“手把手”终端模拟12345678910111213PS C:\MyCode g date_sort.cpp -o date_sort.exe -stdc11PS C:\MyCode .\date_sort.exe--- 原始顺序 ---10-12-202305-01-202415-12-202302-02-2023--- 日历排序后 ---02-02-202310-12-202315-12-202305-01-2024顿悟时刻排序成功std::sort正确地理解了我们的“日历规则”将 2023 年的日期排在了 2024 年的前面。第四部分“X光透 视”——亲眼目睹“规则”被调用我们无法也不需要用调试器“步入” (F11)std::sort内部因为它是一个高度优化的、编译好的“黑盒”。但是我们可以“步入”它调用我们的“自定义规则” (compareDates)