如何按两个值而不是仅按第二个值对向量对进行排序?

How do I sort a vector of pairs by both of the values rather than just the second one?

我想要做的是以第一个值从最低到最大,第二个从最大到最低的方式对向量对进行排序,并且优先于第一个值排序,同时将它们保持在一起。例如,假设我有这个代码:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    pair<int, double> p;
    vector<pair<int, double> > vp;
    p.first = 2;
    p.second = 2.4;
    vp.push_back(p);
    
    p.first = 9;
    p.second = 3.0;
    vp.push_back(p);
    
    p.first = 10;
    p.second = 3.1;
    vp.push_back(p);
    
    p.first = 1;
    p.second = 2.4;
    vp.push_back(p);
    
    p.first = 5;
    p.second = 3.1;
    vp.push_back(p);
}

如果我要通过循环将其打印出来,我希望它不再输出:

2, 2.4
9, 3.0
10, 3.1
1, 2.4
5, 3.1

输出这个

5, 3.1
10, 3.1
9, 3.0
1, 2.4
2, 2.4

现在想象一下,如果这些值不是手动给出的,而是随机的,并且在每次代码为 运行 时循环从 0 到 100(含)之间的随机次数的 for 循环随机化,该对两侧的每个新随机值都存储在向量中(这将使向量的大小为 10。)

如何整理矢量,使其输出的顺序与上述示例相同?

最简单的方法是使用标准函数 std::sort()std::tie()

这里有一个演示程序:

#include <iostream>
#include <utility>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
    std::vector<std::pair<int, double>> v =
    {
        {  2, 2.4 },
        {  9, 3.0 },
        { 10, 3.1 },
        {  1, 2.4 },
        {  5, 3.1 }
    };

    std::sort( std::begin( v ), std::end( v ),
               []( const auto &p1, const auto &p2 )
               {
                   return std::tie( p2.second, p1.first ) < std::tie( p1.second, p2.first );
               } );

    for (const auto &p : v)
    {
        std::cout << p.first << ' ' << p.second << '\n';
    }
}

程序输出为:

5 3.1
10 3.1
9 3
1 2.4
2 2.4

std::sort()与自定义比较器一起使用,例如:

#include <algorithm>

std::sort(vp.begin(), vp.end(),
    [](const std::pair<int, double> &p1, const std::pair<int, double> &p2){
        if (p1.second > p2.second) return true;
        if (p1.second < p2.second) return false;
        return p1.first < p2.first;
    }
);

输出:

5, 3.1
10, 3.1
9, 3
1, 2.4
2, 2.4

Online Demo