c++算法| 排序 | 99% 程序员必踩的浮点数 + 排序坑
浮点数不能直接比大小 + 排序的隐藏技巧 / 致命坑点,一篇彻底讲透,看完直接避开 80% 的 BUG。
using namespace std;// ==================== 核心1:浮点数比较(排序必用!)====================// 原理:float是二进制近似存储,直接==>/</=必出错// 正确方案:放大转整数比较(无精度损耗,排序最稳定)const int SCALE = 1000000; // 放大系数,支持小数点后6位精度bool floatCompare(float a, float b) {long long na = llround(a * SCALE);long long nb = llround(b * SCALE);return na < nb; // 升序}// ==================== 核心2:自定义排序(结构体/对象排序)====================struct Student {int id;float score; // 浮点数分数!坑点密集区};// 排序规则:分数升序,分数相同则id升序bool studentSort(const Student& s1, const Student& s2) {long long n1 = llround(s1.score * SCALE);long long n2 = llround(s2.score * SCALE);if (n1 != n2) return n1 < n2;return s1.id < s2.id;}int main() {// ==================== 坑1:浮点数直接比较错误 ====================cout << "===== 浮点数直接比较错误演示 =====" << endl;float a = 0.1f + 0.2f, b = 0.3f;cout << "0.1+0.2 = " << a << ", 0.3 = " << b << endl;cout << "直接==结果:" << (a == b ? "相等" : "不相等") << endl << endl;// ==================== 正确:浮点数放大转整数比较 ====================cout << "===== 正确:放大转整数比较 =====" << endl;cout << "放大后比较结果:" << (llround(a*SCALE) == llround(b*SCALE) ? "相等" : "不相等") << endl << endl;// ==================== 坑2:浮点数直接排序错误 ====================cout << "===== 浮点数直接排序(错误)=====" << endl;vector<float> arr = {0.3, 0.1+0.2, 0.5, 0.2};sort(arr.begin(), arr.end()); // 直接用默认比较,精度丢失导致乱序for (auto f : arr) cout << f << " ";cout << endl << endl;// ==================== 正确:浮点数专用排序 ====================cout << "===== 浮点数放大转整数排序(正确)=====" << endl;sort(arr.begin(), arr.end(), floatCompare);for (auto f : arr) cout << f << " ";cout << endl << endl;// ==================== 实战:结构体+浮点数 综合排序 ====================cout << "===== 结构体+浮点数 综合排序 =====" << endl;vector<Student> stus = {{1, 90.5f}, {2, 85.3f}, {3, 90.5f}, {4, 92.1f}};sort(stus.begin(), stus.end(), studentSort);for (auto& s : stus) cout << "id:" << s.id << " 分数:" << s.score << endl;// ==================== 排序隐藏坑点总结 ====================cout << "n===== 排序必背坑点 =====" << endl;cout << "1. 整数排序:直接用sort,无坑n";cout << "2. 浮点数排序:禁止直接比,必须放大转整数n";cout << "3. 字符串排序:默认按ASCII,中文需指定编码n";cout << "4. 结构体排序:必须写自定义比较函数,禁止省略n";cout << "5. 稳定性:stable_sort()保留相等元素顺序,sort()不保证n";cout << "6. 降序排序:直接用greater<>()或自定义函数n";return 0;}
一、浮点数比较 / 排序:所有程序员必踩坑
为什么不能直接比?
- float/double 是二进制近似存储
,无法精确表示 0.1、0.2 这类小数 0.1 + 0.2
计算结果 ≠ 0.3,直接比较会出现逻辑错误 -
排序时直接用默认规则,会出现明明相等却排乱的问题
唯一工程正确方案:放大系数转整数比较
-
放大系数 1000000→ 支持小数点后 6 位精度 -
用 llround()四舍五入,避免截断误差 -
转成 long long后可安全使用 == > < -
排序、判断、逻辑判断全部通用
二、C++ 排序全技巧
1. 基础排序
vector<int> v = {3,1,2};sort(v.begin(), v.end()); // 升序(默认)sort(v.begin(), v.end(), greater<int>()); // 降序
stable_sort(v.begin(), v.end());
3. 字符串排序
-
默认按 ASCII 码 排序 -
中文需用 locale或自定义编码比较
4. 结构体 / 对象排序
- 必须写自定义比较函数
-
含浮点数必须放大转整数再比
5. 部分排序(只排前 N 个)
partial_sort(v.begin(), v.begin()+3, v.end());
nth_element(v.begin(), v.begin()+2, v.end());
三、排序 10 大致命坑点
- 浮点数直接 == 比较
→ 必错 - 浮点数直接排序
→ 乱序 -
比较函数返回 = 或 >= → 崩溃 / 死循环 -
排序函数传值而非传引用 → 效率暴跌 -
字符串默认排序中文乱序 -
忽略稳定性要求用了 sort而非stable_sort -
容器越界、空容器直接排序 -
自定义排序规则矛盾(双向返回 true) -
大数排序溢出(int 改 long long) -
未包含 <algorithm>头文件
四、一句话背会核心规则
- 整数随便排
- 浮点数禁止直接比,必须放大转整数
- 结构体必须自定义排序
- 比较函数只返回 <或>
- 稳定排序用 stable_sort
⚠️ 版权声明
本文为免费文章,欢迎转载。转载请注明出处:一木科技(https://www.pingquan.vip/2026/05/31/c%e7%ae%97%e6%b3%95-%e6%8e%92%e5%ba%8f-99-%e7%a8%8b%e5%ba%8f%e5%91%98%e5%bf%85%e8%b8%a9%e7%9a%84%e6%b5%ae%e7%82%b9%e6%95%b0-%e6%8e%92%e5%ba%8f%e5%9d%91/),并保留原文链接。
装机
还没有评论,来说两句?