您好,欢迎访问一九零五行业门户网

由2个值组合成key的STL map排序问题

在c中,map是典型的关联容器或者叫映射容器(associative container),其中的每一个元素都是由key-value这样成对出现的内容组成的,比如学号和学生之类具有一一对应关系的情形,学号可以作为key,学生对象可以作为key所对应的value。很显然这种情况下的key只
在c++中,map是典型的关联容器或者叫映射容器(associative container),其中的每一个元素都是由key-value这样成对出现的内容组成的,比如学号和学生之类具有一一对应关系的情形,学号可以作为key,学生对象可以作为key所对应的value。很显然这种情况下的key只有一个值,但是,在实际工作中,我们可能会经常需要使用多个值组合起来作为key的情况,比如我们要按照学生的视力和身高进行排序,以决定学生的座位排在前面还是后面,而且还是假定要用map来解决这样的问题(当然,这样的问题有很多其它的解决办法),那应该怎么办呢?
(1)  单值作为key的情形
我们知道map在缺省状态下,其数据是按照key的升序进行排列的。假定我们有一个student类,声明如下:
[cpp] view plaincopy
class student  {  private:           int id;                  // 学号           string name;             // 姓名           float eyesight;          // 视力           float height;            // 身高           float chinese;           // 语文成绩           float english;           // 英文成绩           float math;              // 数学成绩  public:           student(int id, string name,floateyesight, float height,float chinese, float english,float math)           {                     this->id = id;                     this->name = name;                     this->eyesight = eyesight;                     this->height = height;                     this->chinese = chinese;                     this->english = english;                     this->math = math;           }              int get_id()           {                     return id;           }              string get_name()           {                     return name;           }              float get_eyesight()           {                     return eyesight;           }              float get_height()           {                     return height;           }              float get_chinese()           {                     return chinese;           }              float get_english()           {                     return english;           }              float get_math()           {                     return math;           }  };   那么下面的程序:
[cpp] view plaincopy
int main(int argc,char**argv)  {         mapint, student> stu_map;    // int作为key的类型,student作为value的类型         stu_map.insert(make_pair(4,student(4, dudley,1.1f, 170.2f, 90.5f, 89.5f, 93.0)));         stu_map.insert(make_pair(3,student(3, chris, 1.1f, 163.4f, 93.5f,90.0f, 83.5f)));         stu_map.insert(make_pair(2,student(2, bob, 1.5f, 166.6f, 86.0f,98.5f, 85.0f)));         stu_map.insert(make_pair(1,student(1, andrew, 1.5f, 173.2f, 98.5f,100.0f, 100.f)));            mapint, student>::iterator iter;         for(iter = stu_map.begin(); iter != stu_map.end();++iter)         {                coutfirst \tsecond.get_name()        }            return 0;  }   就会按照学号的升序给出输出:
1          andrew
2          bob
3          chris
4          dudley
这是缺省的情形,如果要将学生的姓名按照学号的降序输出,那么仅需将上面main函数中的
mapint,student> stu_map;改为
mapint,student, greaterint> > stu_map;
以及
mapint,student>::iterator iter;改为
mapint,student, greaterint> >::iteratoriter;
即可。
其实,mapint,student> stu_map;这是一种缺省的情况,它和
mapint,student, lessint> > stu_map;是一样的。
(2) 多值组合作为key的情形
现在,我们来看看多个值组合起来作为key的情况,为此,我们需要为key定义一个类,如下:
[cpp] view plaincopy
class key  {  public:         float eyesight;         float height;            key(float x, floaty):eyesight(x), height(y)         {         }            friend bool operator const key&);  };     bool operator const key& key2)  {         // 按eyesight升序 + height升序排列         if(key1.eyesight != key2.eyesight)                      return (key1.eyesight        else                return (key1.height                // 按eyesight降序 + height降序排列         //if(key1.eyesight != key2.eyesight)             //     return(key1.eyesight > key2.eyesight);         //else                                          //     return(key1.height > key2.height);            // 按eyesight升序 + height降序排列         //if(key1.eyesight != key2.eyesight)             //     return(key1.eyesight          //else                                          //     return(key1.height > key2.height);            // 按eyesight降序 + height升序排列         //if(key1.eyesight != key2.eyesight)             //     return(key1.eyesight > key2.eyesight);         //else                                          //     return(key1.height   }   再修改main函数如下:
[cpp] view plaincopy
int main(int argc,char**argv)  {         map stu_map;            studentstu4(4, dudley,1.1f, 170.2f, 90.5f, 89.5f, 93.0);         studentstu3(3, chris, 1.1f, 163.4f, 93.5f,90.0f, 83.5f);         studentstu2(2, bob, 1.5f, 166.6f, 86.0f,98.5f, 85.0f);         studentstu1(1, andrew, 1.5f, 173.2f, 98.5f,100.0f, 100.f);            stu_map.insert(make_pair(key(stu4.get_eyesight(),stu4.get_height()), stu4));         stu_map.insert(make_pair(key(stu3.get_eyesight(),stu3.get_height()), stu3));         stu_map.insert(make_pair(key(stu2.get_eyesight(),stu2.get_height()), stu2));         stu_map.insert(make_pair(key(stu1.get_eyesight(),stu1.get_height()), stu1));            map::iterator iter;         for(iter = stu_map.begin(); iter != stu_map.end();++iter)         {               coutfirst.eyesight \tfirst.height  \t second.get_id()\t second.get_name()        }            return 0;  }  
那么输出结果为:
1.1    163.4        3       chris
1.1    170.2        4       dudley
1.5    166.6        2       bob
1.5    173.2        1       andrew
从上面的输出,我们可以很明显地看到,是按照视力升序和升高升序输出的,另外三种可能的排序情况,也在类key的操作符“
(3)结论
1.通常我们不用stl algorithm中的sort函数,来对一个map进行排序,而对vector的元素进行排序则可以很方面地使用sort函数;
2.多值组合作为key的情况,需要我们自己定义一个key类,并在该类中重载操作符“
附两个值作为key的情况之完整的实验代码如下:
[cpp] view plaincopy
#include   #include   #include   using namespace std;      class key  {  public:         float eyesight;         float height;            key(float x, floaty):eyesight(x), height(y)         {         }            friend bool operator const key&);  };     bool operator const key& key2)  {         // 按eyesight升序 + height升序排列         if(key1.eyesight != key2.eyesight)                      return (key1.eyesight        else                return (key1.height                // 按eyesight降序 + height降序排列         //if(key1.eyesight != key2.eyesight)             //     return(key1.eyesight > key2.eyesight);         //else                                          //     return(key1.height > key2.height);            // 按eyesight升序 + height降序排列         //if(key1.eyesight != key2.eyesight)             //     return(key1.eyesight          //else                                          //     return(key1.height > key2.height);            // 按eyesight降序 + height升序排列         //if(key1.eyesight != key2.eyesight)             //     return(key1.eyesight > key2.eyesight);         //else                                          //     return(key1.height   }     class student  {  private:           int id;                   //学号           string name;              // 姓名           float eyesight;           //视力           float height;             //身高           float chinese;            //语文成绩           float english;            //英文成绩           float math;               //数学成绩  public:         student(int id, string name,floateyesight,float height,float chinese,float english,float math)         {                this->id = id;                this->name = name;                this->eyesight = eyesight;                this->height = height;                this->chinese = chinese;                this->english = english;                this->math = math;         }            int get_id()         {                return id;         }            string get_name()         {                return name;         }            float get_eyesight()         {                return eyesight;         }            float get_height()         {                return height;         }            float get_chinese()         {                return chinese;         }            float get_english()         {                return english;         }            float get_math()         {                return math;         }  };     int main(int argc,char**argv)  {         map stu_map;            studentstu4(4, dudley,1.1f, 170.2f, 90.5f, 89.5f, 93.0);         studentstu3(3, chris, 1.1f, 163.4f, 93.5f,90.0f, 83.5f);         studentstu2(2, bob, 1.5f, 166.6f, 86.0f,98.5f, 85.0f);         studentstu1(1, andrew, 1.5f, 173.2f, 98.5f,100.0f, 100.f);            stu_map.insert(make_pair(key(stu4.get_eyesight(),stu4.get_height()), stu4));         stu_map.insert(make_pair(key(stu3.get_eyesight(),stu3.get_height()), stu3));         stu_map.insert(make_pair(key(stu2.get_eyesight(),stu2.get_height()), stu2));         stu_map.insert(make_pair(key(stu1.get_eyesight(),stu1.get_height()), stu1));            map::iterator iter;         for(iter = stu_map.begin(); iter != stu_map.end();++iter)         {               coutfirst.eyesight \tfirst.height  \t second.get_id()\t second.get_name()        }            return 0;  }
其它类似信息

推荐信息