sort/stable_sort 自定义比较功能导致一些奇怪的问题
Posted
技术标签:
【中文标题】sort/stable_sort 自定义比较功能导致一些奇怪的问题【英文标题】:Sort/stable_sort custom compare function cause some strange issues 【发布时间】:2020-01-21 03:00:51 【问题描述】:我对 sort/stable_sort API 的自定义函数有非常基本的经验。 下面是我在 Windows Visual Studio 2017 下运行的源代码。 请帮助分析是什么问题,我错过了什么或者背后的理论是什么?感谢您的帮助
// 10_3_1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX_INPUT_NO (10u)
typedef bool(* sort_func_t)(const int input_a, const int input_b);
bool is_shorter(const int input_a, const int input_b)
#if 0
//this portion will show the iteration overlap
if (input_a > input_b)
return false;
else
return true;
#else
//both below works
//return input_a < input_b;
return input_a > input_b;
#endif
void elimDups(vector<int> &dat, sort_func_t func)
vector<int>::iterator temp = dat.begin();
std::stable_sort(dat.begin(), dat.end(), func);
//sort(dat.begin(), dat.end());
temp = unique(dat.begin(), dat.end());
dat.erase(temp, dat.end());
void print_vec(vector<int> &dat)
vector<int>::const_iterator index = dat.cbegin();
int i = 0;
for (; index < dat.cend(); index++)
cout << "dat[" << i << "] = " << dat.at(i++) << endl;
int main()
vector<int> a;
int ia[MAX_INPUT_NO] = 0, 1, 2, 1, 2, 3, 1, 2, 4, 5;
a.assign(ia, ia + MAX_INPUT_NO);
print_vec(a);
elimDups(a, is_shorter);
print_vec(a);
getchar();
return 0;
但我在玩 if-else 部分时遇到的问题是,它给了我无效的比较器断言错误。
如果我像下面这样定义自定义函数,使用 if-else 模式,它可以正常工作。
bool is_shorter(const int input_a, const int input_b)
#if 1
//this portion will show the iteration overlap
if (input_a > input_b)
return true;
else
return false;
#else
//below works
return input_a > input_b;
#endif
下面是我得到的结果。
期待第 1 项的结果
如果我像下面这样定义自定义比较器函数,它也使用 if-else 模式,它将失败并出现“无效比较器”错误。
bool is_shorter(const int input_a, const int input_b)
#if 1
//this portion will show the iteration overlap
if (input_a > input_b)
return false;
else
return true;
#else
//below works
return input_a > input_b;
#endif
以下是我收到的错误消息:
来自 Visual Studio 2017 的错误消息
但如果我只使用 return,那么它在两个方向上都可以正常工作。
bool is_shorter(const int input_a, const int input_b)
#if 0
//this portion will show the iteration overlap
if (input_a > input_b)
return false;
else
return true;
#else
//both below works
//return input_a < input_b;
return input_a > input_b;
#endif
【问题讨论】:
自定义比较器必须有严格的弱排序。<
和 >
的关系都具有严格的弱排序,但 <=
和 >=
没有。它失败了,因为比较器在input_a <= input_b
时返回true
。
【参考方案1】:
这段代码:
if (input_a > input_b)
return false;
else
return true;
是一种复杂的说法:
return !(input_a > input_b);
greater then
的否定是less or equal
:
return input_a <= input_b; // logically same as before
问题是您不能使用less or equal
关系进行排序,因为它不提供算法所需的严格弱排序。不过你可以少用:
return input_a < input_b;
或大于您在代码中使用时所使用的。
【讨论】:
如果调试构建完成,Visual Studio 的某些(或全部?)版本将捕获 @Slava,感谢您的解释。 @zengweitotty 请阅读What should I do when someone answers my question?以上是关于sort/stable_sort 自定义比较功能导致一些奇怪的问题的主要内容,如果未能解决你的问题,请参考以下文章