如何按降序和第二个元素对对向量进行排序?

时间:2014-03-13 20:21:34

标签: c++ sorting std-pair

我正在进行编程挑战,我在询问之前已经查看了这个主题:

Sorting elements of vector where each element is a pair [duplicate]

How do I sort a vector of pairs based on the second element of the pair?

情况是这样的:

- 我有我的矢量对:vector< pair<int, int> > rank;

- 我已经实现了一个谓词来比较和排序第二个元素的对矢量并按降序排序:

struct predicate
{
    bool operator()(const std::pair<int, int> &left, const std::pair<int, int> &right) 
    {
         return left.second < right.second;
    }
}

sort(rank.rbegin(), rank.rend(), predicate());

编程挑战将为第二个元素提供重复值,对于这种情况,我必须在插入到对矢量时将第一个元素排序,例如:

K V
1 3
2 4
4 5
33 3

排序必须是:

4 5
2 4
1 3
33 3

当我使用我设计的测试用例测试我的解决方案时出现问题:

K V
1 2
16 3
11 2
20 3
18 2
39 39
23 22
12 19
123 4
145 6
3 5
26 4
9574 4
7 1
135 5
193 99
18237 3
22 4
1293 3
3471 33

在对矢量进行排序之后,它应该是这样的输出:

193 99
39 39
3471 33
23 22
12 19
145 6
3 5
135 5
123 4
26 4
9574 4
22 4
16 3
20 3
18237 3
1293 3
1 2
11 2
18 2
7 1

但不是这样,我得到了第一个值排序的元素:

193 99
39 39
3471 33
23 22
12 19
145 6
3 5
135 5
123 4
26 4
9574 4
22 4
20 3 ->Changed element
16 3 ->Changed element
18237 3
1293 3
18 2 ->Changed element
11 2
1 2 ->Changed element
7 1

为什么会这样?我究竟做错了什么?? 帮助将不胜感激

3 个答案:

答案 0 :(得分:4)

std :: sort不保证&#34;等于&#34;的顺序元素保持不变。为此你想要std :: stable_sort。 &#34;等&#34;在这种情况下,意味着两个元素a和b

!((a < b) || (b < a))

答案 1 :(得分:1)

尝试以下代码

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

int main()
{
    std::vector<std::pair<int, int>> v;

    // If your compiler does not support list initialization then you can use push_back
    v.push_back( std::pair<int, int>( 1, 3 ) );
    v.push_back( std::pair<int, int>( 2, 4 ) );
    v.push_back( std::pair<int, int>( 4, 5 ) );
    v.push_back( std::pair<int, int>( 33, 3 ) );

    // The lambda expression can be substituted for a function with the same body
    std::sort( v.begin(), v.end(),
               []( const std::pair<int, int> &p1, const std::pair<int, int> &p2 )
               {
                   return ( p1.second > p2.second || 
                          ( !( p2.second > p1.second ) && p1.first < p2.first ) );
               } );

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

输出

4       5
2       4
1       3
33      3

您的谓词将采用以下方式

struct predicate
{
    bool operator ()( const std::pair<int, int> &left, const std::pair<int, int> &right ) const
    {
        return ( left.second > right.second || 
               ( !( right.second > left.second ) && left.first < right.first ) );
    }
};

答案 2 :(得分:0)

它被称为stable_sort,这意味着如果第二个值相同,那么它将按照与输入相同的排序,如16 3在输入中的20 3之前。所以结果16 3将在20 3之前。在c ++代码中,您应该添加stable_sort()而不是sort()。这是我接受的代码:

#include <bits/stdc++.h>
using namespace std;
bool compare( const pair<long long int,long long int>& x, const pair<long long int, long long int>& y )
{

    return (x.second>y.second);

}
int main()
{
    vector<pair<long long int,long long int> >a;
    long long int n,i,j,b,c;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>b>>c;
        a.push_back(pair<long long int,long long int>(b,c));
    }
    stable_sort(a.begin(),a.end(),compare); //must include stable_sort
    vector<pair<long long int,long long int> >::iterator p;
    for(p=a.begin();p!=a.end();p++)
    {
        cout<<p->first<<" "<<p->second<<endl;
    }
    return 0;



}