由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
-
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)
-
{
-
map<int, 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)));
-
-
map<int, Student>::iterator iter;
-
for(iter = stu_map.begin(); iter != stu_map.end();++iter)
-
{
-
cout<< iter->first << "\t"<< iter->second.get_name() << endl;
-
}
-
-
return 0;
-
}
就会按照学号的升序给出输出:
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
-
class key
-
{
-
public:
-
float eyesight;
-
float height;
-
-
key(float x, floaty):eyesight(x), height(y)
-
{
-
}
-
-
friend bool operator < (constkey&,const key&);
-
};
-
-
bool operator < (constkey& key1,const key& key2)
-
{
-
// 按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 > key2.eyesight);
-
//else
-
// return(key1.height > key2.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 > key2.eyesight);
-
//else
-
// return(key1.height < key2.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)
-
{
-
cout<< iter->first.eyesight << "\t"<< iter->first.height << "\t" << iter->second.get_id()<<"\t" <second.get_name() << endl;
-
}
-
-
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 < (constkey&,const key&);
-
};
-
-
bool operator < (constkey& key1,const key& key2)
-
{
-
// 按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 > key2.eyesight);
-
//else
-
// return(key1.height > key2.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 > key2.eyesight);
-
//else
-
// return(key1.height < key2.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)
-
{
-
cout<< iter->first.eyesight << "\t"<< iter->first.height << "\t" << iter->second.get_id()<<"\t" <second.get_name() << endl;
-
}
-
-
return 0;
-
}