内部元素有序排列,新元素插入的位置取决于它的值,查找速度快。
除了各容器都有的函数外,还支持以下成员函数:
find: 查找等于某个值 的元素(x小于y和y小于x同时不成立即为相等)
lower_bound : 查找某个下界
upper_bound : 查找某个上界
equal_range : 同时查找上界和下界
count :计算等于某个值的元素个数(x小于y和y小于x同时不成立即为相等)
insert: 用以插入一个元素或一个区间
template<class Key, class Pred = less<Key>,
class A = allocator<Key> >
class multiset { …… };
Pred类型的变量决定了multiset 中的元素,“一个比另一个小”是怎么定义的。multiset运行过程中,比较两个元素x,y的大小的做法,就是生成一个 Pred类型的变量,假定为 op,若表达式op(x,y) 返回值为true,则 x比y小。
Pred的缺省类型是 less< Key>。
less 模板的定义:
template < class T>
struct less : public binary_function<T, T, bool>
{
bool operator()(const T& x, const T& y) { return x < y ; } const;
};
#include<iostream>
#include<set>
using namespace std;
template <class T>
void print(T first, T second)
{
for(; first!=second; first++)
cout<<*first<<" ";
cout<<endl;
}
class A
{
private:
int n;
public:
A(int n):n(n) { }
friend bool operator<(const A & a1, const A & a2);
friend ostream & operator<<(ostream & o, const A & a);
friend class MyLess;
};
bool operator<(const A & a1, const A & a2)
{
return a1.n<a2.n;
}
ostream & operator<<(ostream & o, const A &a)
{
o<<a.n;
return o;
}
struct MyLess
{
bool operator()(const A & a1, const A & a2){
return (a1.n % 10) < (a2.n % 10);
}
};
typedef multiset<A> MSET1;
typedef multiset<A, MyLess> MSET2;
int main()
{
const int SIZE = 6;
int a[SIZE] = { 53, 4, 39, 15, 82, 22};
MSET1 m1;
m1.insert(a, a+SIZE);
m1.insert(22);
cout<<m1.count(22)<<endl;
print(m1.begin(), m1.end());
MSET1::iterator p = m1.find(39);
if(p != m1.end()) cout<<"found"<<endl;
cout<<*m1.lower_bound(22)<<", "<<*m1.upper_bound(22)<<endl;
m1.erase(m1.lower_bound(22), m1.upper_bound(22));
print(m1.begin(), m1.end());
MSET2 m2;
m2.insert(a, a+SIZE);
print(m2.begin(), m2.end());
set<int> s1;
s1.insert(a, a+SIZE);
typedef set<int>::iterator IT;
pair<IT, bool> result;
result = s1.insert(22);
if(result.second) cout<<"succeed"<<endl;
else cout<<"faild"<<endl;
pair<IT, IT> bounds = s1.equal_range(22);
cout<<*bounds.first<<", "<<*bounds.second<<endl;
return 0;
}
输出:
2
4 15 22 22 39 53 82
found
22, 39
4 15 39 53 82
82 22 53 4 15 39
faild
22, 39
template<class _T1, class _T2>
struct pair
{
typedef _T1 first_type;
typedef _T2 second_type;
_T1 first;
_T2 second;
pair(): first(), second() { }
pair(const _T1& __a, const _T2& __b): first(__a), second(__b) { }
template<class _U1, class _U2>
pair(const pair<_U1, _U2>& __p): first(__p.first), second(__p.second) { }
};
map/multimap容器里放着的都是pair模版类的对象,且按first从小到大排序。
第三个构造函数用法示例:
pair<int,int>
p(pair<double,double>(5.5,4.6));
// p.first = 5, p.second = 4
template<class Key, class T, class Pred = less<Key>,class A = allocator<T> >
class multimap {
…
typedef pair<const Key, T> value_type;
……
}; //Key 代表关键字的类型
multimap中的元素由 <关键字,值>组成,每个元素是一个pair对象,关键字就是first成员变量,其类型是Key。
multimap 中允许多个元素的关键字相同。元素按照first成员变量从小到大排列,缺省情况下用 less< Key> 定义关键字的“小于”关系。
#include <iostream>
#include <map>
using namespace std;
template <class Key, class Value>
ostream & operator << (ostream & os, const pair<Key, Value> & p)
{
os<<"("<<p.first<<", "<<p.second<<")";
return os;
}
int main()
{
typedef map<int, double, less<int> > mmid;
mmid pairs;
cout<<pairs.count(15)<<endl;
pairs.insert(mmid::value_type(15, 2.7));
pairs.insert(make_pair(15, 99.3));
cout<<pairs.count(15)<<endl;
pairs.insert(make_pair(20, 9.3));
mmid::iterator i;
for(i=pairs.begin(); i!=pairs.end(); i++)
cout<<*i<<", ";
cout<<endl;
int n = pairs[40];
for(i=pairs.begin(); i!=pairs.end(); i++)
cout<<*i<<", ";
cout<<endl;
pairs[15] = 6.28;
for(i=pairs.begin(); i!=pairs.end(); i++)
cout<<*i<<", ";
cout<<endl;
return 0;
}
输出:
0
1
(15, 2.7), (20, 9.3),
(15, 2.7), (20, 9.3), (40, 0),
(15, 6.28), (20, 9.3), (40, 0),
写一个学生成绩录入和查询系统,接受以下两种输入:
Add name id score
Query score
name是个字符串,中间没有空格,代表学生姓名。 id是个整数,代表学号。 score是个整数,表示分数。学号不会重复,分数和姓名都可能重复。两种输入交替出现。第一种输入表示要添加一个学生的信息,碰到这种输入,就记下学生的姓名、 id和分数。第二种输入表示要查询,碰到这种输入,就输出已有记录中分数比score低的最高分获得者的姓名、学号和分数。如果有多个学生都满足条件,就输出学号最大的那个学生的信息。如果找不到满足条件的学生,则输出“ Nobody”。
输入样例:
Add Jack 12 78
Query 78
Query 81
Add Percy 9 81
Add Marry 8 81
Query 82
Add Tom 11 79
Query 80
Query 81
输出结果样例:
Nobody
Jack 12 78
Percy 9 81
Tom 11 79
Tom 11 79
程序:
#include<iostream>
#include<map>
#include<string>
using namespace std;
class Student
{
public:
struct Info
{
int id;
string name;
};
int score;
Info info;
};
typedef multimap<int, Student::Info> MAP_STU;
int main()
{
MAP_STU map;
Student stu;
string cmd;
while(cin>>cmd){
if(cmd == "Add"){
cin>>stu.info.name>>stu.info.id>>stu.score;
map.insert(MAP_STU::value_type(stu.score, stu.info));
}else if(cmd == "Query"){
int score;
cin>>score;
MAP_STU::iterator p = map.lower_bound(score);
if(p!=map.begin()){
--p;
MAP_STU::iterator maxp = p;
int maxId = p->second.id;
for(; p!=map.begin() && p->first==score; --p){
if(p->second.id > maxId){
maxp = p;
maxId = p->second.id;
}
}
//如果p=map.begin
if(p->first == score && p->second.id > maxId){
maxp = p;
maxId = p->second.id;
}
cout<<maxp->second.name<<" "<<maxp->second.id<<" "<<maxp->first<<endl;
}else{
cout<<"No body"<<endl;
}
}
}
return 0;
}