如何在c ++中使用两个排序条件(对于一组对)创建有序集?

时间:2016-05-31 00:50:51

标签: c++

我需要订购一组对(一个是int,第二个是char),我需要按照这样的顺序排序: 12 G,11 F,10 A,10 B,10 C(按第一个降序排列,按秒升序排列) 首先。这是我到目前为止所尝试的,我得到了一些错误:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <utility>
#include <set>

using namespace std;
set <pair <int,char> > s;

bool myfunction( const pair<int, char>& i, const pair<int, char>& j ) {
    if( i.first < j.first ) return false;
    if( j.first < i.first ) return true;
    return j.second < i.second;
}

void writes()
{   set <pair<int,char> >::iterator it;
    for (it = s.begin();it<= s.end();it++) /// line (18)
        cout<<(*it).second<<" "<<(*it).first<<"\n\n";
}
int main()
{   ifstream f("info.in");
    int n;
    f>>n;
    for (int i=1;i<=n;i++)
    {   pair<int,char> x;
        int st;
        char nd;
        f>>st;
        f>>nd;
        x.first=st;
        x.second=nd;
        s.insert(x);
    }
    writes();
}

我得到的第一个错误是在第(18)行:不匹配&#39;运算符&lt; =&#39; (操作数类型是&#39; std :: set&gt; :: .....

非常感谢您的帮助

我的输入文件如下所示:

5
10 B
10 A
10 C
11 F
12 G
@Sam Varshavchik,谢谢!这解决了我的错误问题。 但是,我仍然没有得到我需要的输出。 我只得到:

10 A
10 B
10 C
11 F
12 G

是否可以更改配对中的订单条件?如果没有,你会建议使用什么?

程序仍然忽略了订购标准的myfunction。怎么我在我的对内超载它?看起来,它只是坐在那里,它从未使用过。无论

,程序都能正常工作

我也试过这个:Using custom std::set comparator 但它还没有工作

using namespace std;

struct lex_compare {
    bool operator()(const pair<int, char>& i, const pair<int, char>& j )
{
   if( i.first != j.first )
   {
      return (i.first > j.first);
   }

   return (j.second > i.second);
}
} // forgot ";", after adding it, it works perfectly.
set <pair <int,char>, lex_compare > s; ///line (22)

void writes()
{   set <pair<int,char> >::iterator it;
    for (it = s.begin();it!= s.end();it++) /// line (18)
        cout<<(*it).second<<" "<<(*it).first<<"\n\n";
}
int main()
{   ifstream f("info.in");
    int n;
    f>>n;
    for (int i=1;i<=n;i++)
    {   pair<int,char> x;
        int st;
        char nd;
        f>>st;
        f>>nd;
        x.first=st;
        x.second=nd;
        s.insert(x);
    }
    writes();
}

错误:第(22)行:在声明之前声明无效&#39;;

4 个答案:

答案 0 :(得分:2)

for (it = s.begin();it<= s.end();it++)

通常,迭代器不会实现比类型更少/更大的比较。通常,迭代器仅实现==!=比较,测试是否相等。这应该是:

for (it = s.begin();it != s.end();it++)

(只能使用<>运算符安全地比较随机访问迭代器,而std::set迭代器不是随机访问迭代器)

这回答了你提出的问题:编译错误。这个问题与你的自定义集合比较函数没有任何关系;这将是一个不同的问题。

答案 1 :(得分:0)

基于

  

按第一个降序排列,按第二个升序排序

比较功能必须是:

bool myfunction( const pair<int, char>& i, const pair<int, char>& j )
{
   if( i.first != j.first )
   {
      return (i.first > j.first);
   }

   return (j.second < i.second);
}

然后,确保在使用set时使用它。而不是使用

set <pair <int,char> > s;

使用

set <pair <int,char>, mycompare > s;

这将需要对您的计划进行一些更改。

  1. 在定义mycompare之前,您需要声明/定义s
  2. 迭代器类型也需要更改。

    set <pair<int,char> >::iterator it;
    

    需要:

    set <pair<int,char>, mycompare >::iterator it;
    

    如果您使用的编译器支持C ++ 11,您也可以使用auto

    void writes()
    {
       auto it = s.begin();
       for ( ; it != s.end(); it++)
       {
          cout<<(*it).second<<" "<<(*it).first<<"\n\n";
       }
    }
    

答案 2 :(得分:0)

你永远不会打电话给public static void DisplayInsults(string[] sInsults) { for (int i = 0; i < sInsults.Length; i++) { System.Console.Out.WriteLine(sInsults[i]); } 或用它做任何事情!

要使用它来订购你的套装,请将myfunction转换为仿函数,如下所示:

myfunction

然后用它作为比较器声明该集合,如

struct comparepair {
    bool operator()( const pair<int, char>& i, const pair<int, char>& j ) {
        if( i.first < j.first ) return false;
        if( j.first < i.first ) return true;
        return i.second < j.second;
    }
};

答案 3 :(得分:0)

为了使用自定义比较器,您必须告诉容器有关上面链接的SO问题中描述的函数/仿函数。

以下是您案例的工作示例。

#include <iostream>
#include <set>

typedef std::pair<int, char> pic_t;


struct comp {
    bool operator () ( const pic_t& p1, const pic_t& p2 ) const {
        return ( p1.first != p2.first ) ? ( p1.first > p2.first ) : ( p1.second < p2.second );
        //  identical, slightly better performance:
        //  return ( p1.first > p2.first ) || ( ! ( p2.first > p1.first ) && ( p1.second < p2.second ) );
    }
};


int main()
{
    std::set<pic_t, comp> s = { { 10, 'b' }, { 10, 'a' }, { 10, 'c' }, { 11, 'f' }, { 12, 'g' } };

    for ( auto p : s )
        std::cout << p.first << ", " << p.second << std::endl;

    return 1;
}