C++ 为什么std::sort比较失败?
我有一个无符号整数的向量。父向量的每个元素都是三个无符号整数的向量。我主要希望按照子向量的第一个元素的降序对父向量进行排序,但我也希望按照第三个元素的升序对具有相同第一个元素的任何子向量进行排序。我最初是用以下代码实现的:C++ 为什么std::sort比较失败?,c++,sorting,vector,std,C++,Sorting,Vector,Std,我有一个无符号整数的向量。父向量的每个元素都是三个无符号整数的向量。我主要希望按照子向量的第一个元素的降序对父向量进行排序,但我也希望按照第三个元素的升序对具有相同第一个元素的任何子向量进行排序。我最初是用以下代码实现的: sort(league_vector.begin(), league_vector.end()); reverse(league_vector.begin(), league_vector.end()); sort(league_vector.begin(), league_
sort(league_vector.begin(), league_vector.end());
reverse(league_vector.begin(), league_vector.end());
sort(league_vector.begin(), league_vector.end(),
[](const std::vector<unsigned int>& a, const std::vector<unsigned int>& b) {return a[0] == b[0] && a[2] < b[2];});
排序(league_vector.begin()、leagu_vector.end());
反向(league_vector.begin(),league_vector.end());
排序(league_vector.begin()、league_vector.end(),
[](const std::vector&a,const std::vector&b){返回a[0]==b[0]&a[2]
所以只需排序,然后倒序,整个过程将按第一个元素排序。然后,使用lambda函数进行自定义排序,只有当第三个元素较小而第一个元素相等时,该函数才应返回true
当父向量中的元素数量相对较少(大约50个或更少)时,这似乎效果不错,但当我的元素数量超过这个数量时,最终的排序会变得非常混乱,根本没有明显的模式
我已将其替换为单个自定义排序:
sort(league_vector.begin(), league_vector.end(),
[](const std::vector<unsigned int>& a, const std::vector<unsigned int>& b)
{return ((a[0] > b[0]) || (a[0] == b[0] && a[2] < b[2]));});
排序(league\u vector.begin()、leagu\u vector.end(),
[](常数标准::向量&a,常数标准::向量&b)
{return((a[0]>b[0])| |(a[0]==b[0]&&a[2]
因此,当第一个元素较大时,或者当第三个元素较小且第一个元素相同时,返回true。这似乎很好,所以我只是使用它,但我不知道第一种方法有什么问题。特别是当第一种方法在某些时候似乎有效时,第二种比较只是第一种方法的扩展。首先,
std::sort
不是一种稳定的排序,这意味着它不保留等价元素的顺序。如果需要稳定排序,请使用std::stable\u sort
。此外,您的自定义比较函数没有意义。让我们分析一下它的行为:
如果a[0]
等于b[0]
,则函数返回比较a[2]
和b[2]
的结果。但是,如果a[0]
不等于b[0]
,则函数始终返回false。因为等价定义为!(a
,根据比较函数,具有不同第一个元素的任何两个向量都是相等的
此函数也不是有效的比较函数,因为它不满足严格的弱序。具有不同第一元素的任意两个向量相等,但具有相同第一元素的两个向量不一定相等。这意味着如果
a={1,2,3}
,b={2,3,4}
,和c={1,3,4}
,a==b
和b==c
但a!=c
首先,std::sort
不是一个稳定的排序,这意味着它不保留等价元素的顺序。如果需要稳定排序,请使用std::stable\u sort
。此外,您的自定义比较函数没有意义。让我们分析一下它的行为:
如果a[0]
等于b[0]
,则函数返回比较a[2]
和b[2]
的结果。但是,如果a[0]
不等于b[0]
,则函数始终返回false。因为等价定义为!(a
,根据比较函数,具有不同第一个元素的任何两个向量都是相等的
此函数也不是有效的比较函数,因为它不满足严格的弱序。具有不同第一元素的任意两个向量相等,但具有相同第一元素的两个向量不一定相等。这意味着如果
a={1,2,3}
,b={2,3,4}
,和c={1,3,4}
,a==b
和b==c
但a!=c
为什么第一次尝试失败了?让我们举一个具体的例子来关注这个比较,并试图通过简单的测试来解释为什么这是无效的。
以下是两个联盟向量作为示例:
std::vector<std::vector<unsigned int>> league_vector = {{1,2,3,4}, {2,3,4,5}, {4,5,6,7}};
集中精力:
a[0]==b[0]
假设std::sort
按此顺序比较leagu_vector
中的前两个向量
a={1,2,3,4}b={2,3,4,5}
您的比较函数将返回false
,因为a[0]!=b[0]
然后,如果编译器进行了一次切换,然后给出了正确的结果,只是为了看看您的函数是否不含糊:
a={2,3,4,5}b={1,2,3,4}
换句话说,一个简单的值切换。由于a[0]!=b[0]
如果您在第一次测试中说a
应在b
之后,而在第二次测试中,仅使用切换值,a
应在b
之后,这又有什么意义呢
排序算法有理由变得混乱,并将值按非正统顺序排列
请注意,VisualStudio编译器执行我描述的这个测试,其中给出了比较函数
a
和b
,检查返回值,然后检查b
和a
,并检查返回值。如果存在所指出的不一致,调试运行时将以“无效比较”(或类似)条件断言。为什么第一次尝试失败?让我们举一个具体的例子来关注这个比较,并试图通过简单的测试来解释为什么这是无效的。
以下是两个联盟向量作为示例:
std::vector<std::vector<unsigned int>> league_vector = {{1,2,3,4}, {2,3,4,5}, {4,5,6,7}};
集中精力:
a[0]==b[0]
假设std::sort
按此顺序比较leagu_vector
中的前两个向量
a={1,2,3,4}b={2,3,4,5}
你的比较