一、 标准模板库(StandardTemplate Library,STL)
1、十大容器
1) 线性容器
A.向量(vector):单端开放的动态数组。(只能在尾端增删)
B.双端队列(deque):两端开放的动态数组
C.列表(list):双向线性链表
2)适配器容器
A.堆栈(stack):后进先出
B.队列(queue):先进先出
C.优先队列(priority_queue):优先级高先出
3)关联容器
A.映射(map):以键作为基准的的存放键-----值对的平衡有序二叉树,键必须唯一。
B.多重映射(multiset):允许键重复的映射。
C.集合(set):只有键没有值的映射。
D.多重集合(Multiple):只有键没有值的多重映射。
2、向量
1)基本特性
A.连续内存空间,提供通过下标访问元素的方式。O(1)
B.动态内存管理,同时也支持静态预分配。
2)实例化
#include<vector>
A.空向量
vector<元素类型>向量对象;
vector<int> vi;
B.预分配
vector<元素类型>向量对象(初始大小);
vector<int>vi (3);// 0 0 0
基本类型:用相应类型的“0”初始化
类类型:调用缺省构造函数初始化
C.设初值
vector<元素类型> 向量对象(初值大小,初值);
vector<int> vi(3,5); // 5 5 5
vector<student> vs(3,Student(“张飞”,20));
D .从其他容器复制
Vector<元素类型> 向量对象(源起始迭代器,源终止迭代器);
注意:在STL中凡是提到一个范围的终止迭代器,其实是该范围中最后一个元素的下一个位置的迭代器。
int ai[5]={10,20,30,40,50};
vector<int> v1(ai,ai+5);// 10 20 30 40 50
vector<int> v2(&ai[0],&ai[5]); // 10 20 30 40 50
vector<int> v3(ai+1,ai+4);// 20 30 40
vector<int> v4(&ai[1],&ai[4]);// 20 30 40
举例:vi vec1.cpp
#include <iostream>
#include <vector>
using namespace std;
void print (vector<int> const&vi) {
cout<< "字节数:"<< sizeof (vi) << endl;
size_tsize = vi.size ();
cout<< "元素数:"<< size << endl;
cout<< "元素值:";
for(size_t i = 0; i < size; ++i)
cout<< vi[i] << ' ';
cout<< endl;
}
int main (void) {
vector<int>v1;
print(v1);
vector<int>v2 (3);
print(v2);
vector<int>v3 (3, 5);
print(v3);
intai[5] = {10, 20, 30, 40, 50};
vector<int>v4 (&ai[0], &ai[5]);
print(v4);
vector<int>v5 (ai + 1, ai + 4);
print(v5);
return0;
}
tarena@tarena-virtual-machine:~/day/day04/day04$./a.out
字节数:12
元素数:0
元素值:
字节数:12
元素数:3
元素值:0 0 0
字节数:12
元素数:3
元素值:5 5 5
字节数:12
元素数:5
元素值:10 20 3040 50
字节数:12
元素数:3
元素值:20 30 40
3) 迭代器
A.随机迭代器和顺序迭代器
随机迭代器比顺序迭代器增加了如下功能:
a) 可以和整数做加减运算-------一次迭代多个位置
b) 同型迭代器可以做大小比较-------反映了元素的顺序
c) 同型迭代器可以做相减运算-------反映了元素的距离
在STL中只有向量和双端队列这两个容器采用的是连续内存的存储结构,因此只有它们的迭代器是随机迭代器,而其它容器都只提供顺序迭代器
B.四个迭代器类型
正向可写迭代器:iterator
正向只读迭代器:const_iterator
反向可写迭代器:reverse_iterator
反向只读迭代器:const_reverse_iterator
C.八个特征迭代器
begin( ) begin( )const end( ) end( )const
rbegin( ) rbegin( )const rend( ) rend( )const
begin –起始 end –终止
没有r –正向 有r –反向 (r reverse)
不带const – 可写 带const --只读
正向迭代器:起始->首元素,终止->尾元素之后,增(+)向尾,减(-)向首
10 20 30 40 50
^ ^
起始 终止
反向迭代器:起始->尾元素,终止->首元素之前,增(+)向首,减(-)向尾
10 20 30 40 50
^ ^
终止 起始
可写迭代器:可被视如普通指针,可修改其目标元素的值
只读迭代器:可被视如常量指针,不可修改其目标元素的值
可写迭代器 --隐式转换- ->只读迭代器
只读迭代器 --无法转换- ->可写迭代器
Vivec2.cpp
#include <iostream>
#include <vector>
using namespace std;
void print (vector<int> const&vi) {
for(vector<int>::const_iterator it =
vi.begin(); it != vi.end (); ++it)
cout<< /*++*/*it << ' ';
cout<< endl;
}
void rprint (vector<int> const&vi) {
for(vector<int>::const_reverse_iterator
it= vi.rbegin (); it != vi.rend ();
++it)
cout<< *it << ' ';
cout<< endl;
}
int main (void) {
intai[] = {10, 20, 30, 40, 50};
vector<int>vi (ai, ai + 5);
// ++vi[2];
vector<int>::iteratorit1 = vi.begin ();
// ++*++++it1;
++*(it1+2);
cout<< vi[2] << endl; // 31
it1= vi.end ();
// ++*------it1;
++*(it1- 3);
cout<< vi[2] << endl; // 32
print(vi);
rprint(vi);
it1= vi.begin () + 1;
vector<int>::iteratorit2 = vi.end () - 2;
//10 20 32 40 50
// it1 it2
cout<< boolalpha << (it1 < it2) << endl;
//true
cout<< it1 - it2 << endl; // -2
//it1 + 2 == it2
vector<int>::reverse_iteratorit3 =
vi.rbegin() + 1, it4 = vi.rend() - 2;
//10 20 32 40 50
// it4 it3
cout<< (it3 < it4) << endl; // true
cout<< it3 - it4 << endl; // -2;
//it3 + 2 == it4
return0;
}
D.任何可能造成向量布局发生变化的操作,比如增删元素,操作之前获得的迭代器有可能因该操作而失效。
Vivec3.cpp
#include <iostream>
#include <vector>
using namespace std;
int main (void) {
vector<int>vi;
vi.push_back(100); // vi: 100
vector<int>::iteratorit = vi.begin ();
cout<< *it << endl; // 100
vi.push_back(200); // vi: 100 200
cout<<*it<<endl;// 0(旧地址())
it= vi.begin ();
cout<< *it << endl; //100
return0;
}
4)成员函数
T& front(void);
T const& front(void) const;
T& back (void);
T const& back(void) const;
Void push_back(T const& data);
Void pop_back(void);
Iterator insert(iterator pos , T const&data);
Iterator erase(iterator pos);
举例:
Viprint.h
#include <iostream>
using namespace std;
template<typename IT>
void print (IT begin, IT end) {
while(begin != end)
cout<< *begin++ << ' ';
cout<< endl;
}
Vivec4.cpp
#include <vector>
#include "print.h"
int main (void) {
vector<int>vi;
for(int i = 0; i < 10; ++i)
vi.push_back(i + 1);
print(vi.begin (), vi.end ());
//1 2 3 4 5 6 7 8 9 10
vi.pop_back();
vi.pop_back();
vi.pop_back();
print(vi.begin (), vi.end ());
//1 2 3 4 5 6 7
cout<< vi.front () << ' ' << vi.back ()
<<endl; // 1 7
/*风险
vi.push_front(0); // 向量是单向的
vi.pop_front();
*/
vi.insert(vi.begin (), 0); // 复杂度 O(N)
print(vi.begin (), vi.end ());
//0 1 2 3 4 5 6 7
/*风险
vector<int>::iteratorit = vi.begin () + 4; //指向4
vi.erase(it); //删除 4
print(vi.begin (), vi.end ());
//0 1 2 3 5 6 7
--it;//指向3
vi.erase(it); // 删除3 不安全
print(vi.begin (), vi.end ()); //0 1 2 5 6 7
*/
vector<int>::iteratorit = vi.begin () + 3;
vi.erase(vi.erase (it));
print(vi.begin (), vi.end ());
//0 1 2 5 6 7
return0;
}
5)查找和排序
#include<algorith>//STL泛型算法头文件
IT find(IT begin , IT end , KEY const &key);
在[begin , end]区间内查找第一个和key匹配的元素,如果查找成功,返回指向该匹配元素的迭代器,如果查找失败,返回第二个参数end。
如果容器元素的类型是自定义的类,那么需要重载“= =”操作符,否则find函数无法进行元素判等运算,导致编译失败。
Vifind.cpp 查找
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Complex {
public:
Complex(int r = 0, int i = 0) :
m_r(r), m_i (i) {}
booloperator== (Complex const& c) const {
returnm_r == c.m_r && m_i == c.m_i;
}
friendostream& operator<< (ostream& os,
Complexconst& c) {
returnos << c.m_r << '+' << c.m_i <<'i';
}
private:
intm_r, m_i;
};
int main (void) {
intai[] = {10, 20, 30, 40, 50};
for(size_t i = 0; i < sizeof (ai) /
sizeof(ai[0]); ++i)
cout<< &ai[i] << ' ';
cout<< endl;
int*pi = find (&ai[0], &ai[5], 30);
cout<< pi << endl;
pi= find (&ai[0], &ai[5], 25);
cout<< pi << endl;
vector<int>vi (ai, ai + 5);
vector<int>::iteratorit = find (vi.begin (),
vi.end(), 30);
if(it == vi.end ())
cout<< "没找到!"<< endl;
else
cout<< "找到了:"<< *it << endl;
it= find (vi.begin (), vi.end (), 25);
if(it == vi.end ())
cout<< "没找到!"<< endl;
else
cout<< "找到了:"<< *it << endl;
vector<Complex>vc (5);
vc[0]= Complex (1, 2);
vc[1]= Complex (3, 4);
vc[2]= Complex (5, 6);
vc[3]= Complex (7, 8);
vc[4]= Complex (9, 10);
vector<Complex>::iteratori = find (
vc.begin(), vc.end (), Complex (5, 6));
if(i == vc.end ())
cout<< "没找到!"<< endl;
else
cout<< "找到了:"<< *i << endl;
return0;
}
0xbfe4ade4 0xbfe4ade8 0xbfe4adec 0xbfe4adf00xbfe4adf4
0xbfe4adec
0xbfe4adf8
找到了:30
没找到!
找到了:5+6i
Void sort(IT begin , IT end) ;
通过小于运算符比大小
在[begin , end) 区间内做快速升序排序 时间复杂度 O(N logN)
Void sort(IT begin , IT end , less) ;
通过小于比较器比大小。
vi.sort.cpp 排序
#include <algorithm>
#include <vector>
#include "print.h"
class Student {
public:
Student(string const& name, int score) :
m_name(name), m_score (score) {}
/*
booloperator< (Student const& st) const {
// returnm_name < st.m_name;
returnm_score > st.m_score;
}
*/
friendostream& operator<< (ostream& os,
Studentconst& st) {
returnos << '(' << st.m_name << ','
<<st.m_score << ')';
}
private:
stringm_name;
intm_score;
friendbool stuCmpByName (Student const&,
Studentconst&);
friendclass StuCmpByScore;
};
bool stuCmpByName (Student const& sa,
Studentconst& sb) {
returnsa.m_name < sb.m_name;
}
class StuCmpByScore {
public:
booloperator() (Student const& sa,
Studentconst& sb) const {
if(sa.m_score == sb.m_score)
returnsa.m_name < sb.m_name;
returnsa.m_score > sb.m_score;
}
};
int main (void) {
vector<int>vi;
vi.push_back(33);
vi.push_back(17);
vi.push_back(29);
vi.push_back(11);
vi.push_back(31);
print(vi.begin (), vi.end ());
sort(vi.begin (), vi.end ());
print(vi.begin (), vi.end ());
sort(vi.rbegin (), vi.rend ());
print(vi.begin (), vi.end ());
vector<Student>vs;
vs.push_back(Student ("zhangfei", 90));
vs.push_back(Student ("zhaoyun", 80));
vs.push_back(Student ("guanyu", 70));
vs.push_back(Student ("huangzhong", 80));
vs.push_back(Student ("machao", 70));
vs.push_back(Student ("liubei", 90));
vs.push_back(Student ("caocao", 90));
vs.push_back(Student ("zhouyu", 40));
print(vs.begin (), vs.end ());
// sort(vs.begin (), vs.end ());
// sort(vs.begin (), vs.end (), stuCmpByName);
sort(vs.begin (), vs.end (),
StuCmpByScore());
print(vs.begin (), vs.end ());
return0;
}
tarena@tarena-virtual-machine:~/day/day05/day05$./a.out
33 17 29 11 31
11 17 29 31 33
33 31 29 17 11
(zhangfei,90) (zhaoyun,80) (guanyu,70)(huangzhong,80) (machao,70) (liubei,90) (caocao,90) (zhouyu,40)
(caocao,90) (liubei,90) (zhangfei,90)(huangzhong,80) (zhaoyun,80) (guanyu,70) (machao,70) (zhouyu,40)
6)类类型元素
A.缺省构造函数:创建具有初始大小的向量,需要通过缺省构造函数初始化其中的元素对象。
B.支持深拷贝的拷贝构造函数和拷贝赋值运算符函数:向量容器内部保存的都是对象副本,而且对容器进行增删时,同样需要复制元素对象。
C.为了避免过于频繁的对象复制所带来的性能损失,可以用向量保存对象的指针,但是这些对象的创建和销毁需要手动完成。
D.如果使用find做线性查找,元素类型需要支持“= =”运算符。
E.如果使用sort做快速排序,元素类型需要支持“<”运算符,或者提供相应类型的小于比较器(函数或仿函数)。
Vi vec5.cpp
#include <iostream>
#include <vector>
using namespace std;
class A {
public:
A(void) {
cout<< "缺省构造:"<< this << endl;
}
A(A const& a) {
cout<< "拷贝构造:"<< &a << "->"
<<this << endl;
}
A&operator= (A const& a) {
cout<< "拷贝赋值:"<< &a << "->"
<<this << endl;
}
~A(void) {
cout<< "析构函数:"<< this << endl;
}
};
int main (void) {
cout<< "-------- 1 --------" << endl;
vector<A>va (3);
cout<< "-------- 2 --------" << endl;
va.push_back(A ());
cout<< "-------- 3 --------" << endl;
va.erase(va.begin ());
cout<< "-------- 4 --------" << endl;
Aa1, a2, a3;
vector<A*>vp;
vp.push_back(&a1);
vp.push_back(&a2);
vp.push_back(&a3);
cout<< "-------- 5 --------" << endl;
vector<A*>vn;
vn.push_back(new A);
vn.push_back(new A);
vn.push_back(new A);
for(vector<A*>::iterator it = vn.begin ();
it!= vn.end (); ++it)
delete*it;
return0;
}
tarena@tarena-virtual-machine:~/day/day05/day05$./a.out
-------- 1 --------
缺省构造:0xbff4eeaa
拷贝构造:0xbff4eeaa->0x8fdc008
拷贝构造:0xbff4eeaa->0x8fdc009
拷贝构造:0xbff4eeaa->0x8fdc00a
析构函数:0xbff4eeaa
-------- 2 --------
缺省构造:0xbff4eeac
拷贝构造:0xbff4eeac->0x8fdc01b
拷贝构造:0x8fdc008->0x8fdc018
拷贝构造:0x8fdc009->0x8fdc019
拷贝构造:0x8fdc00a->0x8fdc01a
析构函数:0x8fdc008
析构函数:0x8fdc009
析构函数:0x8fdc00a
析构函数:0xbff4eeac
-------- 3 --------
拷贝赋值:0x8fdc019->0x8fdc018
拷贝赋值:0x8fdc01a->0x8fdc019
拷贝赋值:0x8fdc01b->0x8fdc01a
析构函数:0x8fdc01b
-------- 4 --------
缺省构造:0xbff4eead
缺省构造:0xbff4eeae
缺省构造:0xbff4eeaf
-------- 5 --------
缺省构造:0x8fdc028
缺省构造:0x8fdc050
缺省构造:0x8fdc008
析构函数:0x8fdc028
析构函数:0x8fdc050
析构函数:0x8fdc008
析构函数:0xbff4eeaf
析构函数:0xbff4eeae
析构函数:0xbff4eead
析构函数:0x8fdc018
析构函数:0x8fdc019
析构函数:0x8fdc01a
3、双端队列
除了前端开放以外,双端队列和向量几乎完全一样。为了维持首尾两端的开放性,双端队列在内存空间和运行时间上比向量略差。
比向量多了两个成员函数:push_front/ pop_front
#include<deque>
deque<int> di;
deque<int> di(3);
deque<int> di(3,10);
deque<int> di(ai,ai+5);
4、列表
#include<list>
template<typename T> classlist<T>;
双向线性链表,不支持下标操作符,只支持顺序迭代,插入和删除效率高。时间复杂度(O(1))
1)唯一化
void unique (void) ;
将链表中连续重复出现的元素唯一化。
2) 排序
void sort(void);
利用元素类型的“<”比大小。
void sort(LESS less);
利用小于比较器(函数或仿函数)比大小。
注意,<algorithm>头文件中声明的全局函数sort只适用于提供随机迭代器的容器,如向量、双端队列,不能用于只提供顺序迭代器的容器,如列表。
3) 拆分
将参数列表的部分或全部元素剪切到调用列表的特定位置处。
void splid(IT pos,list& lst); //剪全部
void splid(IT pos,list& lst,ITdel); //剪一个
void splid(IT pos,list& lst,IT beg,ITend ); //剪一段
从参数列表lst 中剪切全部/一个/一段 元素,插入到调用列表的pos之前。
时间复杂度(O(1))
4) 合并
void merge(list& lst);
将有序的参数列表lst中的元素合并到有序的调用列表中,合并后的结果依然有序。
void merge(list& lst,LESS less); 降序用比较器或伪函数
时间复杂度:O(N)
vi.list
#include <list>
//#include <algorithm>
#include "print.h"
bool intCmp (int a, int b) {
returna > b;
}
class IntCmp {
public:
IntCmp(bool raise = true) :
m_raise(raise) {}
booloperator() (int a, int b) const {
if(m_raise)
returna < b;
else
returna > b;
}
private:
boolm_raise;
};
int main (void) {
intai[]={10,10,20,20,10,20,30,20,20,10,10};
list<int>l1 (ai, ai + 11);
print(l1.begin (), l1.end ());
// sort(l1.begin (), l1.end ());
// l1.sort();
// l1.sort(intCmp);
// l1.sort(IntCmp ());
l1.sort(IntCmp (false));
print(l1.begin (), l1.end ());
l1.unique();
print(l1.begin (), l1.end ()); // 30 20 10
list<int>l2;
l2.push_back(1000);
l2.push_back(2000);
l2.push_back(3000);
l2.push_back(4000);
l2.push_back(5000);
print(l2.begin (), l2.end ());
list<int>::iteratorpos = l1.end ();
/*
l1.splice(--pos, l2);
*//*
list<int>::iteratordel =l2.begin ();
l1.splice(--pos, l2, ++++del);
*/
list<int>::iteratorbeg = l2.begin (),
end= l2.end ();
l1.splice(--pos, l2, ++beg, --end);
print(l1.begin (), l1.end ());
print(l2.begin (), l2.end ());
l1.clear();
l1.push_back(13);
l1.push_back(17);
l1.push_back(21);
l1.push_back(33);
l1.push_back(49);
l2.clear();
l2.push_back(9);
l2.push_back(11);
l2.push_back(15);
l2.push_back(19);
l2.push_back(20);
l2.push_back(25);
l2.push_back(61);
print(l1.begin (), l1.end ());
print(l2.begin (), l2.end ());
l1.merge(l2);
print(l1.begin (), l1.end ());
print(l2.begin (), l2.end ());
return0;
}
tarena@tarena-virtual-machine:~/day/day05/day05$./a.out
10 10 20 20 10 20 30 20 20 10 10
30 20 20 20 20 20 10 10 10 10 10
30 20 10
1000 2000 3000 4000 5000
30 20 2000 3000 4000 10
1000 5000
13 17 21 33 49
9 11 15 19 20 25 61
9 11 13 15 17 19 20 21 25 33 49 61
5、堆栈、队列和优先队列
适配器容器<元素类型,[底层容器类型]>
1) 堆栈
#include<stack>
push -> push_back;
pop ->pop_back;
top -> back
size -> size
empty -> empty
底层容器:vector/deque/list
2) 队列
#include<queue>
push ->push_back
pop-> pop_back
front->front
back->back
size -> size
empty -> empty
底层容器:deque(缺省)/list
3) 优先队列
缺省优先级:大者为优
#include<queue>
push/pop/top
底层容器:vector/deque(缺省)
1 7 3 9 2 6 5
首------ > 尾
9 7 6 5 3 2 1
利用类似插入排序的逻辑,保证每压入一个元素,都能够被插入到合适的位置,保证队列有序。因此,任何时候从队首弹出的都是当前队列中优先级最高的元素。
priority_queue<元素类型,底层容器类型> //通过“<”比大小
priority_queue<元素类型,底层容器类型> //通过比较器比大小
比较器只能用仿函数,不能用函数指针
visqp.cpp
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <list>
using namespace std;
class IntCmp {
public:
booloperator() (int a, int b) const {
returna > b;
}
};
int main (void) {
// stack<string,vector<string> > ss;
// stack<string,list<string> > ss;
stack<string/*,deque<string>*/> ss;
ss.push("C++!");
ss.push("喜欢");
ss.push("我们");
while(! ss.empty ()) {
cout<< ss.top ();
ss.pop();
}
cout<< endl;
// queue<string,vector<string> > qs;
// queue<string,list<string> > qs;
queue<string/*,deque<string>*/> qs;
qs.push("我们");
qs.push("喜欢");
qs.push("STL!");
while(! qs.empty ()) {
cout<< qs.front ();
qs.pop();
}
cout<< endl;
// priority_queue<int>pi;
priority_queue<int,deque<int>, IntCmp> pi;
// priority_queue<int,list<int> > pi;
pi.push(7);
pi.push(1);
pi.push(5);
pi.push(2);
pi.push(9);
pi.push(3);
pi.push(6);
pi.push(4);
pi.push(8);
while(! pi.empty ()) {
cout<< pi.top () << ' ';
pi.pop();
}
cout<< endl;
return0;
}
tarena@tarena-virtual-machine:~/day/day05/day05$./a.out
我们喜欢C++!
我们喜欢STL!
1 2 3 4 5 6 7 8 9
6、映射、多重映射、集合、多重集合
1)映射
#include<map>
A.保存“键------值”对,表示一一对应的逻辑关系。
键 值
张飞-----90
赵云-----80
关羽-----70
B.通过一个关于键的平衡有序二叉树(红黑树)保存键值组合,可以在对数时间(O(logN))内根据特定的键找到与之对应的值。
C.键必须唯一,根据一个键只能找到唯一的值,一对一。
D.基于迭代器的遍历循环,实际上对二叉树做中序遍历,得到的是一个关于键的升序序列。
E.结点中的数据元素的类型是pair类模板的实例,其中的first成员表示键,second成员表示值。
template<typename F,typename S>
class pair{
pair(F const& f , S const& s ):first(f),second(s) {}
Ffirst;
Ssecond;
};
映射迭代器相当于pair指针。
E.映射支持以键为参数的下标运算符。
F.映射支持以键为参数的下标运算符,既可以插入元素,也可以查找元素
2)多重映射
#include<map>
A. 允许键重复,一个键对应多个值,一多对应。
B. 不支持下标运算符
3)集合
#incluce<set>
没有值的映射
4) 多重集合
#include<set>
没有值的多重映射
vi.map,cpp
#include <iostream>
#include <map>
#include <set>
using namespace std;
int main (void) {
map<string,int> si;
si["张飞"] = 90;
si.insert(pair<string, int> ("赵云", 80));
si.insert(make_pair ("关羽", 70));
cout<< si["赵云"] << endl; // O(logN)
si["张飞"] = 60;
cout<< si["张飞"] << endl;
si.insert(make_pair ("关羽", 50));
cout<< si["关羽"] << endl;
for(map<string, int>::iterator it =
si.begin(); it != si.end (); ++it)
cout<< it->first << "考了" << it->second
<<"分"<< endl;
multimap<string,int> msi;
msi.insert(make_pair ("张飞", 80));
msi.insert(make_pair ("赵云", 70));
msi.insert(make_pair ("关羽", 60));
msi.insert(make_pair ("张飞", 90));
msi.insert(make_pair ("赵云", 80));
msi.insert(make_pair ("关羽", 70));
typedefmultimap<string, int>::iterator IT;
for(IT it = msi.begin (); it != msi.end ();
++it)
cout<< it->first << ":" << it->second
<<endl;
pair<IT,IT> its = msi.equal_range ("张飞");
for(IT it = its.first; it != its.second;
++it)
cout<< it->first << " = " << it->second
<<endl;
set<int>sa;
sa.insert(10);
sa.insert(20);
sa.insert(10);
sa.insert(10);
sa.insert(30);
sa.insert(20);
sa.insert(30);
for(set<int>::iterator it = sa.begin ();
it!= sa.end (); ++it)
cout<< *it << ' ';
cout<< endl;
multiset<int>msa;
msa.insert(10);
msa.insert(20);
msa.insert(10);
msa.insert(10);
msa.insert(30);
msa.insert(20);
msa.insert(30);
for(multiset<int>::iterator it =
msa.begin(); it != msa.end (); ++it)
cout<< *it << ' ';
cout<< endl;
return0;
}
tarena@tarena-virtual-machine:~/day/day05/day05$./a.out
80
60
70
关羽考了70分
张飞考了60分
赵云考了80分
关羽:60
关羽:70
张飞:80
张飞:90
赵云:70
赵云:80
张飞 = 80
张飞 = 90
10 20 30
10 10 10 20 20 30 30