当前位置:Gxlcms > mysql > 由2个值组合成key的STLmap排序问题

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

时间:2021-07-01 10:21:17 帮助过:47人阅读

在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

  1. class Student
  2. {
  3. private:
  4. int id; // 学号
  5. string name; // 姓名
  6. float eyesight; // 视力
  7. float height; // 身高
  8. float chinese; // 语文成绩
  9. float english; // 英文成绩
  10. float math; // 数学成绩
  11. public:
  12. Student(int id, string name,floateyesight, float height,float chinese, float english,float math)
  13. {
  14. this->id = id;
  15. this->name = name;
  16. this->eyesight = eyesight;
  17. this->height = height;
  18. this->chinese = chinese;
  19. this->english = english;
  20. this->math = math;
  21. }
  22. int get_id()
  23. {
  24. return id;
  25. }
  26. string get_name()
  27. {
  28. return name;
  29. }
  30. float get_eyesight()
  31. {
  32. return eyesight;
  33. }
  34. float get_height()
  35. {
  36. return height;
  37. }
  38. float get_chinese()
  39. {
  40. return chinese;
  41. }
  42. float get_english()
  43. {
  44. return english;
  45. }
  46. float get_math()
  47. {
  48. return math;
  49. }
  50. };

那么下面的程序:

[cpp] view plaincopy

  1. int main(int argc,char**argv)
  2. {
  3. map<int, Student> stu_map; // int作为key的类型,Student作为value的类型
  4. stu_map.insert(make_pair(4,Student(4, "Dudley",1.1f, 170.2f, 90.5f, 89.5f, 93.0)));
  5. stu_map.insert(make_pair(3,Student(3, "Chris", 1.1f, 163.4f, 93.5f,90.0f, 83.5f)));
  6. stu_map.insert(make_pair(2,Student(2, "Bob", 1.5f, 166.6f, 86.0f,98.5f, 85.0f)));
  7. stu_map.insert(make_pair(1,Student(1, "Andrew", 1.5f, 173.2f, 98.5f,100.0f, 100.f)));
  8. map<int, Student>::iterator iter;
  9. for(iter = stu_map.begin(); iter != stu_map.end();++iter)
  10. {
  11. cout<< iter->first << "\t"<< iter->second.get_name() << endl;
  12. }
  13. return 0;
  14. }

就会按照学号的升序给出输出:

1 Andrew

2 Bob

3 Chris

4 Dudley

这是缺省的情形,如果要将学生的姓名按照学号的降序输出,那么仅需将上面main函数中的

map<int,Student> stu_map;改为

map<int,Student, greater<int> > stu_map;

以及

map<int,Student>::iterator iter;改为

map<int,Student, greater<int> >::iteratoriter;

即可。

其实,map<int,Student> stu_map;这是一种缺省的情况,它和

map<int,Student, less<int> > stu_map;是一样的。

(2) 多值组合作为key的情形

现在,我们来看看多个值组合起来作为key的情况,为此,我们需要为key定义一个类,如下:

[cpp] view plaincopy

  1. class key
  2. {
  3. public:
  4. float eyesight;
  5. float height;
  6. key(float x, floaty):eyesight(x), height(y)
  7. {
  8. }
  9. friend bool operator < (constkey&,const key&);
  10. };
  11. bool operator < (constkey& key1,const key& key2)
  12. {
  13. // 按eyesight升序 + height升序排列
  14. if(key1.eyesight != key2.eyesight)
  15. return (key1.eyesight < key2.eyesight);
  16. else
  17. return (key1.height < key2.height);
  18. // 按eyesight降序 + height降序排列
  19. //if(key1.eyesight != key2.eyesight)
  20. // return(key1.eyesight > key2.eyesight);
  21. //else
  22. // return(key1.height > key2.height);
  23. // 按eyesight升序 + height降序排列
  24. //if(key1.eyesight != key2.eyesight)
  25. // return(key1.eyesight < key2.eyesight);
  26. //else
  27. // return(key1.height > key2.height);
  28. // 按eyesight降序 + height升序排列
  29. //if(key1.eyesight != key2.eyesight)
  30. // return(key1.eyesight > key2.eyesight);
  31. //else
  32. // return(key1.height < key2.height);
  33. }

再修改main函数如下:

[cpp] view plaincopy

  1. int main(int argc,char**argv)
  2. {
  3. map stu_map;
  4. Studentstu4(4, "Dudley",1.1f, 170.2f, 90.5f, 89.5f, 93.0);
  5. Studentstu3(3, "Chris", 1.1f, 163.4f, 93.5f,90.0f, 83.5f);
  6. Studentstu2(2, "Bob", 1.5f, 166.6f, 86.0f,98.5f, 85.0f);
  7. Studentstu1(1, "Andrew", 1.5f, 173.2f, 98.5f,100.0f, 100.f);
  8. stu_map.insert(make_pair(key(stu4.get_eyesight(),stu4.get_height()), stu4));
  9. stu_map.insert(make_pair(key(stu3.get_eyesight(),stu3.get_height()), stu3));
  10. stu_map.insert(make_pair(key(stu2.get_eyesight(),stu2.get_height()), stu2));
  11. stu_map.insert(make_pair(key(stu1.get_eyesight(),stu1.get_height()), stu1));
  12. map::iterator iter;
  13. for(iter = stu_map.begin(); iter != stu_map.end();++iter)
  14. {
  15. cout<< iter->first.eyesight << "\t"<< iter->first.height << "\t" << iter->second.get_id()<<"\t" <second.get_name() << endl;
  16. }
  17. return 0;
  18. }


那么输出结果为:

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

  1. #include
  2. #include
  3. #include
  4. using namespace std;
  5. class key
  6. {
  7. public:
  8. float eyesight;
  9. float height;
  10. key(float x, floaty):eyesight(x), height(y)
  11. {
  12. }
  13. friend bool operator < (constkey&,const key&);
  14. };
  15. bool operator < (constkey& key1,const key& key2)
  16. {
  17. // 按eyesight升序 + height升序排列
  18. if(key1.eyesight != key2.eyesight)
  19. return (key1.eyesight < key2.eyesight);
  20. else
  21. return (key1.height < key2.height);
  22. // 按eyesight降序 + height降序排列
  23. //if(key1.eyesight != key2.eyesight)
  24. // return(key1.eyesight > key2.eyesight);
  25. //else
  26. // return(key1.height > key2.height);
  27. // 按eyesight升序 + height降序排列
  28. //if(key1.eyesight != key2.eyesight)
  29. // return(key1.eyesight < key2.eyesight);
  30. //else
  31. // return(key1.height > key2.height);
  32. // 按eyesight降序 + height升序排列
  33. //if(key1.eyesight != key2.eyesight)
  34. // return(key1.eyesight > key2.eyesight);
  35. //else
  36. // return(key1.height < key2.height);
  37. }
  38. class Student
  39. {
  40. private:
  41. int id; //学号
  42. string name; // 姓名
  43. float eyesight; //视力
  44. float height; //身高
  45. float chinese; //语文成绩
  46. float english; //英文成绩
  47. float math; //数学成绩
  48. public:
  49. Student(int id, string name,floateyesight,float height,float chinese,float english,float math)
  50. {
  51. this->id = id;
  52. this->name = name;
  53. this->eyesight = eyesight;
  54. this->height = height;
  55. this->chinese = chinese;
  56. this->english = english;
  57. this->math = math;
  58. }
  59. int get_id()
  60. {
  61. return id;
  62. }
  63. string get_name()
  64. {
  65. return name;
  66. }
  67. float get_eyesight()
  68. {
  69. return eyesight;
  70. }
  71. float get_height()
  72. {
  73. return height;
  74. }
  75. float get_chinese()
  76. {
  77. return chinese;
  78. }
  79. float get_english()
  80. {
  81. return english;
  82. }
  83. float get_math()
  84. {
  85. return math;
  86. }
  87. };
  88. int main(int argc,char**argv)
  89. {
  90. map stu_map;
  91. Studentstu4(4, "Dudley",1.1f, 170.2f, 90.5f, 89.5f, 93.0);
  92. Studentstu3(3, "Chris", 1.1f, 163.4f, 93.5f,90.0f, 83.5f);
  93. Studentstu2(2, "Bob", 1.5f, 166.6f, 86.0f,98.5f, 85.0f);
  94. Studentstu1(1, "Andrew", 1.5f, 173.2f, 98.5f,100.0f, 100.f);
  95. stu_map.insert(make_pair(key(stu4.get_eyesight(),stu4.get_height()), stu4));
  96. stu_map.insert(make_pair(key(stu3.get_eyesight(),stu3.get_height()), stu3));
  97. stu_map.insert(make_pair(key(stu2.get_eyesight(),stu2.get_height()), stu2));
  98. stu_map.insert(make_pair(key(stu1.get_eyesight(),stu1.get_height()), stu1));
  99. map::iterator iter;
  100. for(iter = stu_map.begin(); iter != stu_map.end();++iter)
  101. {
  102. cout<< iter->first.eyesight << "\t"<< iter->first.height << "\t" << iter->second.get_id()<<"\t" <second.get_name() << endl;
  103. }
  104. return 0;
  105. }

人气教程排行