我正在尝试对某些数据实施多属性排序,并通过背靠背stable_sorts
来解决问题:
bool DecreasingA(const Data & a, const Data & b) {
return a.A >= b.A;
}
bool DecreasingB(const Data & a, const Data & b) {
if (a.B)
return true; // if a.B is true, maintain ordering
if (b.B)
return false; // a.B is false, but b.B is true, to swap elements
return true; // a.B and b.B are false, maintain ordering
}
std::vector<Data> myVector;
// add Data to vector here
std::stable_sort(myVector.begin(), myVector.end(), DecreasingA());
std::stable_sort(myVector.begin(), myVector.end(), DecreasingB());
但是在我这样做之后,myVector
的A属性与我想要的顺序相反。即使它在第一个stable_sort
例如:
在排序之前:
A B C
1 0 5
1 1 8
2 0 2
0 1 3
第一次排序(减少A)看起来不错:
A B C
2 0 2
1 0 5
1 1 8
0 1 3
第二次排序后(减少B)我得到了这个:
A B C
0 1 3
1 1 8
1 0 5
2 0 2
而不是我想要的:
A B C
1 1 8
0 1 3
2 0 2
1 0 5
我认为这是我的DecreasingB
函数的一个问题,但我尝试了各种逻辑并继续进行这种反转。有什么建议吗?
我知道我可以编写一个比较函数来处理这种特殊情况,但我需要灵活性让最终用户选择要排序的属性以及它们应用的顺序。
答案 0 :(得分:6)
您的比较功能都已损坏。都没有实现std::stable_sort
所要求的必要的严格弱排序。具体来说,
f(x, x)
必须是假的。f(x, y)
暗示!f(y, x)
两个帐户的功能都失败了。
你可能想要这个:
bool DecreasingA(const Data & a, const Data & b) {
return a.A > b.A; // > instead of >=
}
bool DecreasingB(const Data & a, const Data & b) {
if (a.B == b.B) // both equal, so a does not precede b
return false;
if (b.B) // b.B is true and a.B is false, so a does not precede b
return false;
return true; // a.B is true and b.B is false, so a does precede b
}
答案 1 :(得分:2)
您只需撰写DecreasingBThenA
#include <algorithm>
#include <tuple>
#include <vector>
#include <iostream>
struct Data
{
int A, B, C;
};
bool DecreasingBThenA(const Data & a, const Data & b)
{
return std::tie(a.B, a.A) > std::tie(b.B, b.A);
}
int main()
{
auto myVector = std::vector<Data>
{{ 1, 0, 5}, {1, 1, 8}, {2, 0, 2}, {0, 1, 3}};
std::stable_sort(myVector.begin(), myVector.end(), DecreasingBThenA);
for (auto&& t : myVector)
std::cout << "{" << t.A << ", " << t.B << ", " << t.C << "}\n";
}
产生所需输出的
如果N
中有Data
个元素,并且您希望能够进行任意排序,那么您所需要的只是DecreasingA
到DecreasingN
的比较(每个返回a.X > b.X
数据成员X
),然后使用您想要排序的条件的逆序中的std::sort
进行多次传递。因此,BThenA
需要先A
然后B
进行排序。这与使用逐列排序按钮同时在各种列上对Excel中的数据进行排序的方式相同。
答案 2 :(得分:1)
DecreasingA
不提供排序算法所要求的严格弱排序,因此无法保证任何特定行为。