一、STL的概述
为提高复用性,建立数据结构和算法的一套标准,诞生了STL(Standard Template Library,标准模板库),STL从广义上分为三大组件:容器(container)、算法(algorithm)、迭代器(iterator),容器和算法之间通过迭代器进行无缝连接。.STL几乎所有的代码都采用.模板类或者模板函数,这相比传统的由函数和类组成的库来说提供了更好的代码重用机会。
STL的6大组件:
- 容器:存放数据
- 算法:操作数据
- 迭代器:算法和容器的桥梁,每个容器对应一个迭代器,算法 通过迭代器 操作 容器
- 适配器:为算法 提供更多的接口
- 仿函数:为算法 提供策略
- 空间配置:为算法、容器提供动态空间
算法分类:
- 质变算法:是指运算过程中会更改区间内的元素的内容(会更改容器的值),例如拷贝,替换,删除等等
- 非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻 找极值等等
二、string容器(类)
C++标准库定义了一种string类,定义在头文件。String封装了很多实用的成员方法:查找find,搓贝copy,册除delete,替换replace,插入insert,不用考虑内存释放和越界。
1、构造函数以及赋值函数
string 构造函数
- string();//创建一个空的字符串 例如: string str;
- string(const string& str);//使用一个string对象初始化另一个string对象
- string(const char* s);//使用字符串s初始化
- string(int n, char c);//使用n个字符c初始化
string基本赋值操作函数
- string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
- string& operator=(const string &s);//把字符串s赋给当前的字符串
- string& operator=(char c);//字符赋值给当前的字符串
- string& assign(const char *s);//把字符串s赋给当前的字符串
- string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
- string& assign(const string &s);//把字符串s赋给当前字符串
- string& assign(int n, char c);//用n个字符c赋给当前字符串
- string& assign(const string &s, int start, int n);//将s从start开始n个字符 赋值给字符串
2、存取字符操作
char& operator[](int n);//通过[]方式获取字符
char& at(int n);//通过at方法获取字符
3、拼接操作
- string& operator+=(const string& str);//重载+=操作符
- string& operator+=(const char* str);//重载+=操作符
- string& operator+=(const char c);//重载+=操作符
- string& append(const string &s);//同operator+=()
- string& append(const char *s);//把字符串s连接到当前字符串结尾
- string& append(int n, char c);//在当前字符串结尾添加n个字符c
- string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串 结尾
- string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个 字符连接到当前字符串结尾
4、查找和替换
利用string类中find、rfind和repace函数,注pos为缺省参数。
int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从p os开始查找
int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开 始查找
int find(const char* s, int pos, int n) const; //从pos位置查找s的前n个字符 第一次位置
int find(const char c, int pos = 0) const; //查找字符c第一次出现位置
int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,从 pos开始查找
int rfind(const char* s, int pos = npos) const;//查找s最后一次出现位置,从po s开始查找
int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后 一次位置
int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
string& replace(int pos, int n, const string& str); //替换从pos开始n个字符 为字符串str 10 string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为 字符串s
5、比较操作
> < == != 运算符 可用。
compare函数在>时返回 1,<时返回 ‐1,==时返回 0。
int compare(const string &s) const;//与字符串s比较
int compare(const char *s) const;//与字符串s比较
6、提取子串
string substr(int pos = 0, int n = npos) const;//返回由pos开始的n个字符组成 的字符串
7、插入和删除操作
string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串
string& insert(int pos, int n, char c);//在指定位置插入n个字符c
string& erase(int pos, int n = npos);//删除从Pos开始的n个字符
8、 string和c风格(c-style)字符串转换
三、vector容器(类模板)
1、概述
vector容器:单端动态数组容器。必须包含头文件:#include<vector>
vector的数据安排以及操作方式,与array非常相似,两者的唯一差别在于空间的运用的灵活性。Array是静态空间,配置后再改变空间复杂,Vector是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新元素。
push_back尾部插入元素、pop_back尾部删除元素
front()头元素、back()尾元素
begin()得到的是 容器的 起始迭代器(首元素的位置)
end() 得到的是 结束迭代器(尾元素的下一个元素位置)
iterator迭代器 size()容器中元素的个数 capacity()容器的容量
一旦容量满载,下次再有新增元素,整个vector容器需另外开辟空间。为了降低空间配置时的速度成本,vector实际配置的大小可能比客户端需求大一些,以备将来可能的扩充。
2、相关API
构造函数:
- vector<T> v;//采用模版实现,默认构造函数
- vector(v.begin(), v.end());//将v[ begin(), end()]区间中的元素拷贝给本身
- vector(n, elem);//构造函数将n个elem拷贝给本身。
- vector(const vector &vec);//接贝构造函数。
赋值操作:
- assign(beg,end);//将[ beg,end)区间中的数据拷贝赋值给本身。
- assign(n,elem);//将n个elem拷贝赋值给本身。
- vector& operator=( const vector &vec);//重载等号操作符
- swap(vec);//将vec与本身的元素互换
大小操作:
- size();//返回容器中元素的个数。
- empty();//判断容器是否为空
- resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置,如果容器变短,则末尾超出容器长度的示素被删除。
- capacity();//容器的容量
- reserve(int len);//容器预留len个元素长度,但预留位置不初始化,元素不可访问。
存取操作:
- at(int idx);//返返回索引 idx所指的数据,如果idx越界,抛出out of range异常。
- operator[];返回索引idx所指的数据,越界时,运行直接报错
- front();//返回容器第一个元素
- back();//返回容器中最后一个数据元素
插入和删除:
- insert(const iterator pos,int count,ele);//迭代器指位置pos插入count个元素ele
- push_back(ele);//尾部插入元素ele
- pop_back();//删除最后一个元素
- erase(const_iterator start,const_iterator end);//删除迭代器从start到end之间的元素
- erase(const_iterator pos);/ /删除迭代器指向的元素
- clear();//删除容器中所有元素
举例说明:
//打印
void printVectorInt(vector<int> &v)
{vector<int>::iterator it;for(it=v.begin();it!=v.end();it++){cout<<*it<<" ";}cout<<endl;
}
void test()
{//构造vector<int> v1(5,10);printVectorInt(v1);vector<int> v2=v1;//拷贝构造printVectorInt(v2);vector<int> v3(v1.begin(),v1.end());printVectorInt(v3);//赋值vector<int> v4;//v4=v3;----=运算符重载v4.assign(v3.begin(),v3.end());printVectorInt(v4);v4.assign(5,100);printVectorInt(v4);//交换v3.swap(v4);printVectorInt(v3);printVectorInt(v4);//判断容器是否为空vector<int> v5;if(v5.empty()){cout<<"空"<<endl;}else{cout<<"非空"<<endl;}///重新指定容器的长度vector<int> v6(10,20);cout<<"大小:"<<v6.size()<<"容量:"<<v6.capacity()<<endl;printVectorInt(v6);v6.resize(15);//过大补零//v6.resize(15,30);//过大补30cout<<"大小:"<<v6.size()<<"容量:"<<v6.capacity()<<endl;printVectorInt(v6);v6.resize(10);//容量不变cout<<"大小:"<<v6.size()<<"容量:"<<v6.capacity()<<endl;printVectorInt(v6);//存取vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.at(0)=10;v[1]=20;//可直接赋值printVectorInt(v);//at越界会抛出异常,[]越界不会抛出异常cout<<v.at(0)<<" "<<v[0]<<endl;cout<<"头元素:"<<v.front()<<"尾元素:"<<v.back()<<endl;//插入和删除v.insert(v.begin()+1,3,2);//迭代器指位置pos+1插入3个元素2printVectorInt(v);v.pop_back();//尾部删除printVectorInt(v);v.erase(v.begin()+1,v.begin()+4);//删除三个2printVectorInt(v);v.clear();//大小清0cout<<"大小:"<<v.size()<<"容量:"<<v.capacity()<<endl;
}
运行结果:
3、巧用swap收缩空间
4、vector容器 嵌套 容器
5、使用算法 对 vector容器排序
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
void printVectorInt(vector<int> &v)
{vector<int>::iterator it;for(it=v.begin(); it!=v.end();it++){cout<<*it<<" ";}cout<<endl;
}
bool myCompare(int value1,int value2)
{return value1>value2;
}
void test()
{vector<int> v;v.push_back(1);v.push_back(6);v.push_back(3);v.push_back(9);v.push_back(2);printVectorInt(v);//顺序sort(v.begin(),v.end());printVectorInt(v);//倒序//sort(v.begin(),v.end(), greater<int>());//sort(v1.begin(), v1.end(), myCompare);
}int main(int argc, char *argv[])
{test();return 0;
}
6、vector存放自定义数据类型
class Person
{friend void printVectorPerson(vector<Person> &v);friend bool myComparePerson(const Person &ob1, const Person &ob2);
private:int num;string name;float score;
public:Person(){}Person(int num, string name, float score){this‐>num = num;this‐>name = name;this‐>score = score;}#if 0//方法2:重载自定义数据的<运算符bool operator<(const Person &ob){return this‐>num < ob.num;}#endif
};
void printVectorPerson(vector<Person> &v)
{vector<Person>::iterator it;for(it=v.begin(); it!=v.end(); it++){//*it == Personcout<<(*it).num<<" "<<(*it).name<<" "<<(*it).score<<endl;}
}
//方法1:对于自定义容器排序 必须实现 排序规则
bool myComparePerson(const Person &ob1, const Person &ob2)
{if(ob1.num == ob2.num)return ob1.score>ob2.score;return ob1.num > ob2.num;
}
void test()
{vector<Person> v;v.push_back(Person(1, "lucy", 88.5f));v.push_back(Person(3, "tom", 77.5f));v.push_back(Person(3, "小明", 85.5f));v.push_back(Person(2, "小红", 96.5f));printVectorPerson(v);//方法1:对于自定义容器排序 必须实现 排序规则sort(v.begin(), v.end(), myComparePerson);//方法2:重载自定义数据的<运算符//sort(v.begin(), v.end());cout<<"‐‐‐‐‐‐‐‐‐‐‐‐‐‐"<<endl;printVectorPerson(v);
}
四、deque容器
1、deque的概述
deque:双端动态数组
Deque容器和vector容器的区别:
1、deque允许使用常数项时间对头端进行元素的插入和删除操作。
2、deque没有容量的概念。
无容量概念是因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,不会像vector那样”旧空间不足而重新配置一块更大空间,然后复制元素,再释放旧空间"。也因此,deque没有必须要提供所谓的空间保留(reserve)功能。
2、deque的API
构造函数:
- deque<T> deqT;//采用模版实现,默认构造函数
- deque(v.begin(), v.end());//将v[ begin(), end()]区间中的元素拷贝给本身
- deque(n, elem);//构造函数将n个elem拷贝给本身。
- deque(const vector &deq);//接贝构造函数。
赋值操作:
- assign(beg,end);//将[ beg,end)区间中的数据拷贝赋值给本身。
- assign(n,elem);//将n个elem拷贝赋值给本身。
- deque& operator=( const deque &vec);//重载等号操作符
- swap(deq);//将vec与本身的元素互换
大小操作:
- size();//返回容器中元素的个数。
- empty();//判断容器是否为空
- resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置,如果容器变短,则末尾超出容器长度的示素被删除。
- deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填 充新位置,如果容器变短,则末尾超出容器长度的元素被删除
存取操作:
- at(int idx);//返返回索引 idx所指的数据,如果idx越界,抛出out of range异常。
- operator[];返回索引idx所指的数据,越界时,运行直接报错
- front();//返回容器第一个元素
- back();//返回容器中最后一个数据元素
双端插入删除:
- push_front(elem);//在容器头部插入一个数据
- push_back(ele);//尾部插入元素ele
- pop_front();//删除容器第一个数据
- pop_back();//删除最后一个元素
插入和删除:
- insert(const iterator pos,int count,ele);//迭代器指位置pos插入count个元素ele
- insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值
- insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值
- erase(const_iterator start,const_iterator end);//删除迭代器从start到end之间的元素
- erase(const_iterator pos);/ /删除迭代器指向的元素
- clear();//删除容器中所有元素
如果迭代器能+X 那么该迭代器 为随机访问迭代器
vector存放的数据 没有多大规律,只是纪录数据。
deque容器:用于类似竞技的数据
3、deque容器的案例
有5名选手:选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除评委中 最低分,取平均分。
1. 创建五名选手,放到vector中
2. 遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque 容器中
3. sort算法对deque容器中分数排序,pop_back pop_front去除最高和最低分
4. deque容器遍历一遍,累加分数,累加分数/d.size()
5. person.score = 平均分
#include<vector>
class Player
{
public:string name;float score;
public:Player(){}Player(string name,float score=0.0f)//缺省参数{this‐>name = name;this‐>score=score;}
};
void createPlayer(vector<Player> &v)
{string seedName = "ABCDE";int i=0;for(i=0;i<5;i++){string tmpName = "选手";tmpName+=seedName[i];v.push_back(Player(tmpName));//Player(tmpName)为匿名对象}
}
#include<stdlib.h>
#include<time.h>
#include<algorithm>
void playGame(vector<Player> &v)
{//设置随机数 种子srand(time(NULL));//每名选手都要参加vector<Player>::iterator it;for(it=v.begin(); it!=v.end();it++){//10个评委打分deque<float> d;int i=0;for(i=0;i<10;i++){d.push_back(rand()%41+60);}// 对d容器排序sort(d.begin(),d.end());//去掉最高分d.pop_back();//去掉最低分d.pop_front();//求总分数(*it).score = accumulate(d.begin(),d.end(), 0)/d.size();}
}
void showScore(vector<Player> &v)
{vector<Player>::iterator it;for(it=v.begin(); it!=v.end();it++){cout<<(*it).name<<"所得分数:"<<(*it).score<<endl;}
}
void test()
{//创建5名选手 放入vector容器中vector<Player> v;createPlayer(v);//开始比赛playGame(v);//公布成绩showScore(v);
}
五、stack栈容器
1、stack的概述
stack是一种先进后出(First In Last Out,FILO)的数据结构。它只有一个栈顶出口,但是除了栈顶外,没有任何其他方法可以存取stack 的其他元素。换言之,stack不允许有遍历行为。有元素推入栈的操作称为:push,将元素推出stack 的操作称为pop。
注:
操作数据的一端的顶部叫栈顶。
top永远指向栈顶元素。
栈容器没有迭代器。不支持遍历行为。
2、stack的API
stack构造函数:
- stack<int> T;//stack采用模板类实现, stack对象的默认构造形式
- stack(const stack &stk);//拷贝构造函数
stack赋值操作:
- stack& operator=(const stack &stk);//重载等号操作符
stack数据存取操作:
- push(elem);//向栈顶添加元素
- pop();//从栈顶移除第一个元素
- top();//返回栈顶元素
stack大小操作:
- empty();//判断堆栈是否为空
- size();//返回堆栈的大小
六、queue队列容器
Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。
出数据的一方叫队头,入数据的一方叫队尾。
queue容器没有迭代器 不支持遍历行为。
queue构造函数:
- queue<int> queT;//stack采用模板类实现, queue对象的默认构造形式
- queue(const stack &stk);//拷贝构造函数
queue赋值操作:
- queue& operator=(const stack &stk);//重载等号操作符
queue数据存取操作:
- push(elem);///往队尾添加元素
- pop();//从栈顶移除第一个元素
- back();//返回最后一个元素
- front();//返回第一个元素
queue大小操作:
- empty();//判断堆栈是否为空
- size();//返回堆栈的大小
七、list链表容器
list为双向循环链表,迭代器是 双向迭代器。
构造函数:
- list<T> lstT;//采用模版实现,默认构造函数
- list(v.begin(), v.end());//将v[ begin(), end()]区间中的元素拷贝给本身
- list(n, elem);//构造函数将n个elem拷贝给本身。
- list(const vector &deq);//接贝构造函数。
赋值操作:
- assign(beg,end);//将[ beg,end)区间中的数据拷贝赋值给本身。
- assign(n,elem);//将n个elem拷贝赋值给本身。
- deque& operator=( const deque &vec);//重载等号操作符
- swap(deq);//将vec与本身的元素互换
大小操作:
- size();//返回容器中元素的个数。
- empty();//判断容器是否为空
- resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置,如果容器变短,则末尾超出容器长度的示素被删除。
- deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填 充新位置,如果容器变短,则末尾超出容器长度的元素被删除
存取操作:
- front();//返回容器第一个元素
- back();//返回容器中最后一个数据元素
双端插入删除:
- push_front(elem);//在容器头部插入一个数据
- push_back(ele);//尾部插入元素ele
- pop_front();//删除容器第一个数据
- pop_back();//删除最后一个元素
插入和删除:
- insert(const iterator pos,ele);//迭代器指位置pos插入元素ele
- insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值
- insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值
- erase(const_iterator start,const_iterator end);//删除迭代器从start到end之间的元素
- erase(const_iterator pos);/ /删除迭代器指向的元素
- remove(elem);//删除容器中所有与elem值匹配的元素。
- clear();//删除容器中所有元素
反转排序:
- reverse();//反转链表
- sort(); //list排序
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
void printListInt(list<int> &l)
{list<int>::iterator it;for(it=l.begin();it!=l.end();it++){cout<<*it<<" ";}cout<<endl;
}
void test()
{list<int> l;l.push_front(1);l.push_front(2);l.push_front(3);l.push_back(4);l.push_back(5);l.push_back(6);printListInt(l);//list容器 是双向迭代器 不支持+X 支持++//不支持l.insert(l.begin()+2,3,10);list<int>::iterator it=l.begin();it++;it++;l.insert(it,3,10);printListInt(l);//删除所有10l.remove(10);printListInt(l);//排序//STL提供的算法 只支持 随机访问迭代器,而list是双向迭代器 所以sort不支持list//不支持sort(l.begin(),l.end());l1.sort();// l1.sort(greater<int>());//倒序printListInt(l);}
int main(int argc, char* argv[])
{test();return 0;
}
运行结果:
八、set/mulitset容器
1、set/mulitset的概述
set容器的特征是所有元素都会根据元素的键值自动被排序。Set 不允许两个元素。set的元素即是键值又是实值。,故不能通过set的迭代器改变set元素的值,会破坏set的数据结构。set容器的迭代器是只读迭代器const_iterator。
multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复。set和multiset的底层实现是红黑树,红黑树为平衡二叉树的一种。树的简单知识:二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点。
二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效。二叉搜索树的放置规则是:任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于其右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直至无路可走,可得到最大值。那么在儿茶搜索树中找到最大元素和最小元素是非常简单的事情。
2、set/mulitset的API
set构造函数:
- set<int> st;//set默认构造函数:
- mulitset mst; //multiset默认构造函数:
- set(const stack &stk);//拷贝构造函数
set赋值操作:
- set& operator=(const stack &stk);//重载等号操作符
- swap(st);//交换两个集合容器
set插入和删除操作
- insert(elem);//在容器中插入元素。
- clear();//清除所有元素
- erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
- erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器
- erase(elem);//删除容器中值为elem的元素。
set大小操作:
- empty();//判断堆栈是否为空
- size();//返回堆栈的大小
set查找操作:
- find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回se t.end();
- count(key);//查找键key的元素个数
- lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
- upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
- equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
查找元素的上下限:
用pair对组判断插入是否成功:
3、更改set容器的排序规则(定义set容器时 修改)
一般都是通过 “仿函数” 修改set容器的排序规则。
set<int,排序规则类> s1;
4、如果set容器存放自定义数据 必须更改排序规则
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
class Person
{friend ostream& operator <<(ostream &out,Person s);friend class myGraterPerson;
private:int num;string name;float score;
public:Person(){}Person(int num,string name,float score ){this->name=name;this->num=num;this->score=score;}
};
//仿函数
class myGraterPerson
{
public:bool operator()(Person s1,Person s2){return s1.num<s2.num;}
};
ostream& operator <<(ostream &out,Person s)
{out<<s.num<<" "<<s.name<<""<<s.score<<endl;return out;
}
void printListPerson(set<Person,myGraterPerson> &s)
{set<Person,myGraterPerson>::iterator it;for(it=s.begin();it!=s.end();it++){cout<<(*it);}cout<<endl;
}
void test()
{set<Person,myGraterPerson> s;s.insert(Person(4,"小红",85.5));s.insert(Person(1,"小明",75.5));s.insert(Person(3,"tom",87.5));s.insert(Person(2,"lucy",82.5));s.insert(Person(5,"bob",78.5));printListPerson(s);
}
int main(int argc, char* argv[])
{test();return 0;
}
关键代码及运行结果:
5、multiset容器 键值可以重复
九、pair对组
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值 可以分别用pair的两个公有属性first和second访问。
十、map/multimap容器
1、概述
Map的特性是,所有元素都会根据元素的键值自动排序。Map 所有的元素都是pair,同时拥有实值和键值,pair的第一元素被视为键值,第二元素被视为实值,map不允许两个元素有相同的键值。不能通过map 的迭代器改变map 的键值。Multimap 和map的操作类似,唯一区别multimap键值可重复。底层实现机制是红黑树。
2、API
map构造函数:
- map<T1,T2> mapTT;//map默认构造函数:
- map(const map &mp);//拷贝构造函数
map赋值操作:
- map& operator=(const map &mp);//重载等号操作符
- swap(mp);//交换两个集合容器
map大小操作:
- empty();//判断堆栈是否为空
- size();//返回堆栈的大小
map插入操作
- map.insert(...); //往容器插入元素,返回pair<interator,bool>
- map<int,string> mapStu;
- //举例
- // 第一种 通过pair的方式插入对象
- mapStu.insert(pair<int,string>(1, "小红"));
- mapStu.inset(make_pair(2, "小明"));
- // 第二种 通过value_type的方式插入对象
- mapStu.insert(map<int,string>::value_type(3, "小李"));
- // 第四种 通过数组的方式插入值
- mapStu[1] = "小王";
- mapStu[3] = "小刘";
map删除操作:
- clear();//删除所有元素
- erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
- erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器
- erase(beg,end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器
map查找操作:
- find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回se t.end();
- count(key);//查找键key的元素个数
- lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
- upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
- equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
案例:
#include<iostream>
#include<map>
using namespace std;
class Person
{friend void test();friend void printmapPerson(map<int,Person> &m);private:int num;string name;float score;
public:Person(){}Person(int num,string name,float score){this->name=name;this->num=num;this->score=score;}
};void printmapPerson(map<int,Person> &m)
{map<int,Person>::iterator it;for(it=m.begin();it!=m.end();it++){//*it==pair<int,Person>cout<<"学号:"<<(*it).first<<" "<<"姓名:"<<(*it).second.name<<" \分数:"<<(*it).second.score<<endl;}cout<<endl;
}
void test()
{map<int,Person> m;//插入方式1:m.insert(pair<int,Person>(3, Person(3,"小红", 89.5f)));m.insert(make_pair(1,Person(1,"小明", 87.5f)));//推荐使用//插入方式2:m.insert( map<int, Person>::value_type( 2 , Person(2,"tom",66.6f)));//插入方式3:m[4] = Person(4,"小李", 92.5f);printmapPerson(m);//假如key值存在 m[key]代表对应的实值,若不存在,系统会重新创建。cout<< m[7].num<<" "<<m[7].name<<" "<<m[7].score<<endl;printmapPerson(m);//删除元素m.erase(4);printmapPerson(m);//查找元素对组map<int, Person>::const_iterator ret;ret=m.find(3);if(ret!=m.end()){cout<<"找到该元素:"<< (*ret).first<<" "<<(*ret).second.name<<" "<<(*ret).second.score<<endl;}
}
int main(int argc, char* argv[])
{test();return 0;
}
main关键代码:
3、multimap实际案例
公司今天招聘了5个员工,5名员工进入公司之后,需要指派员工在那个部门工 作 人员信息有: 姓名 年龄 电话 工资等组成 通过Multimap进行信息的插入 保存 显示 分部门显示员工信息 显示全部员工信息。
#include<iostream>
#include<map>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
class Person
{friend void showPartmentPerson(multimap<int,Person> &m);friend void personJoinPartment(multimap<int,Person> &m,vector<Person> &v);private:string name;int age;string tel;int salary;
public:Person(){}Person(string name,int age,string tel,int salary);
};
void personJoinPartment(multimap<int,Person> &m,vector<Person> &v);
void createVectorPerson(vector<Person> &v);
void showPartmentPerson(multimap<int,Person> &m);
void test()
{//创建vector容器存放员工vector<Person> v;createVectorPerson(v);//员工加入部门multimap<int,Person> m;personJoinPartment(m,v);//显示部门成员showPartmentPerson(m);}
int main(int argc, char* argv[])
{test();return 0;
}
void createVectorPerson(vector<Person> &v)
{//设置随机数种子srand(time(NULL));int i=0;for(i=0;i<5;i++){string seedname="ABCDE";string tmpname="员工";tmpname+=seedname[i];int age=20+i;string tel=to_string(rand());int salary=10000+rand()%10*1000;v.push_back(Person(tmpname,age,tel,salary));}
}
void personJoinPartment(multimap<int,Person> &m,vector<Person> &v)
{vector<Person>::iterator it;for(it=v.begin();it!=v.end();it++){//*it=Personcout<<"请输入"<<(*it).name<<"要加入的部门:1(销售)、2(研发)、3(财务)";int op;cin>>op;m.insert(make_pair(op,*it));}
}
void showPartmentPerson(multimap<int,Person> &m)
{cout<<"请输入"<<"要显示的部门:的部门1(销售)、2(研发)、3(财务)";int op;cin>>op;switch (op) {case 1:cout<<"---销售部门---"<<endl;break;case 2:cout<<"---研发部门---"<<endl;break;case 3:cout<<"---财务部门---"<<endl;break;default:break;}multimap<int,Person>::const_iterator ret;ret=m.find(op);int count=m.count(op);for(int i=0;i<count;i++,ret++){//*ret=pair<int, Person>cout<<"\t"<<(*ret).second.name<<" "<<(*ret).second.age<<" "\<<(*ret).second.salary<<" "<<(*ret).second.tel<<endl;}return;
}
Person::Person(string name, int age, string tel, int salary)
{this->name=name;this->age=age;this->tel=tel;this->salary=salary;
}
运行案例:
十一、容器的使用时机
vector的使用场景:比如软件历史操作记录的存储
deque的使用场景:比如排队购票系统,支持头端的快速移除,尾端的快速添加
list的使用场景:比如公交车乘客的存储,随时可能有乘客下车,支持频繁的不 确实位置元素的移除插入
set的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高分到低 分的顺序排列
map的使用场景:比如按ID号存储十万个用户,想要快速要通过ID查找对应的 用户。