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

转自:http://blog.csdn.net/pathuang68/article/details/7526305

某网友问:“map中怎么设置多个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<key,Student> 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<key,Student>::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" <<iter->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 <iostream>

    2. #include <map>

    3. #include <string>

    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<key,Student> 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<key,Student>::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" <<iter->second.get_name() << endl;

    103. }
    104. return 0;

    105. }

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

时间: 2024-10-25 20:48:12

【转】由2个值组合成key的STL map排序问题的相关文章

STL map 按key值和按value值排序

map是用来存放<key, value>键值对的数据结构,能够非常方便高速的依据key查到对应的value. 假如存储水果和其单位价格.我们用map来进行存储就是个不错的选择. 我们这样定义.map<string, double>.当中水果用string类型.作为Key:该水果的单位价格用double类型,作为value. 这样一来,我们能够依据水果名高速的查找到价格. 我们不仅要将水果和相应的价格输出,还想知道依照价格高低进行排序的结果. 换句话说,我们希望可以对map进行按Ke

黑马程序员——通过HashMap的value值,得到key键值

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- HashMap中key值是唯一的,但value是不唯一的:同一个value可能返回多个key下面是个例子:找出value是“value”的key 1 import java.util.HashMap; 2 import java.util.Iterator; 3 import java.util.Map; 4 import java.util.Set; 5 public class HashM

Map四种获取key和value值的方法,以及对map中的元素排序

获取map的值主要有四种方法,这四种方法又分为两类,一类是调用map.keySet()方法来获取key和value的值,另一类则是通过map.entrySet()方法来取值,两者的区别在于,前者主要是先获取到所有的key的集合,当你需要查询value的值的时候需要通过key来查询value,后者则直接将key和value的键值对直接取出来,只用查询一次,对于那种性能更好,我觉得还是用map.entrySet()更好一点,具体请参见map.keySet()和map.EntrySet()的比较,接下

给定N个非0的个位数字,用其中任意2个数字都可以组合成1个2位的数字。要求所有可能组合出来的2位数字的和。例如给定2、5、8,则可以组合出:25、28、52、58、82、85,它们的和为330。

#include<iostream>#include<math.h>#include<stdlib.h>using namespace std;int main(){ /* * 给定N个非0的个位数字,用其中任意2个数字都可以组合成1个2位的数字.要求所有可能组合出来的2位数字的和.例如给定2.5.8,则可以组合出:25.28.52.58.82.85,它们的和为330. 输入格式: 输入在一行中先给出N(1<N<10),随后是N个不同的非0个位数字.数字间以

Map四种获取key和value值的方法,以及对map中的元素排序(转)

获取map的值主要有四种方法,这四种方法又分为两类,一类是调用map.keySet()方法来获取key和value的值,另一类则是通过map.entrySet()方法来取值,两者的区别在于,前者主要是先获取到所有的key的集合,当你需要查询value的值的时候需要通过key来查询value,后者则直接将key和value的键值对直接取出来,只用查询一次,对于那种性能更好,我觉得还是用map.entrySet()更好一点,具体请参见map.keySet()和map.EntrySet()的比较,接下

均值为1的独立指数随机Y1,Y2,组合成的Y=Y1-(Y2-1)^2/2 在Y&gt;0的条件下也是指数随机变量

均值为1的独立指数随机Y1,Y2,组合成的Y=Y1-(Y2-1)^2/2  在Y>0的条件下也是指数随机变量 原文地址:https://www.cnblogs.com/wdfrog/p/11683302.html

python练习:字典value值排序,key值排序

#字典value值排序,key值排序 from random import * dict1 = {x:randint(5,12) for x in "aijwt"} dict2 = {randint(5,12):y for y in "aibjwte"} print ('dict1:',dict1) print ('dict2:',dict2) print ("将字典按value倒序显示,办法(collections的Counter):") fr

java 多种判断key是否在map中存在的方法

java 中有时候会遇到判断传过来的map里是否包含了指定的key,我目前只发现两种办法,如果有其他方法欢迎补充 我添加上去: HashMap map = new HashMap(); map.put("1", "value1"); map.put("2", "value2"); Iterator keys = map.keySet().iterator(); while(keys.hasNext()){ String key

c语言实现名值对通过key查找value

需求.例如: 1." key1 = value1 " 通过"key1"从该字符串中查找出"value",value去除前后空格 2." key1 == value1 " ." key1 = = value1 " 双等于号不合法 头文件: #include<stdlib.h> #include<stdio.h> #include<string.h> 函数原型: void t