11.7 比較函式的鐵則:相等必須回傳 false
自定義比較函式有一條不能踩的紅線。太多人踩過、而且踩了以後幾小時都查不出來,所以它值得獨立成一節。
空口無憑,實驗給你看。十萬個一模一樣的數,用 <= 的比較函式排序:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int x, int y) {
return x <= y; // 相等時回傳 true:災難的開始
}
int main() {
vector<int> v(100000, 7); // 十萬個一模一樣的 7
sort(v.begin(), v.end(), cmp);
cout << "done" << '\n';
return 0;
}
執行結果:
Segmentation fault (core dumped)
程式沒印出 done 就當掉了。在 OJ 上,這種程式的下場依測資而定——RE、WA、TLE 都有可能,而且資料裡相等元素少的時候還可能僥倖通過,換一筆測資才爆炸,特別難查。所以把鐵則背起來:
動手試試看:把上面的實驗程式跑一次,親眼看它當掉;再把 <= 改回 <,確認 done 乖乖出現。然後回頭檢查你在上一節解掉的特殊數字排序——比較函式裡若有任何一個分支在相等時回傳 true,改掉它(改壞一個 < 成 <= 再交一次,觀察 OJ 給你什麼結果也很有教育意義)。