1、map/multimap容器的基本概念
Map的特性是,所有元素都會根據(jù)元素的鍵值自動排序。Map所有的元素都是pair,同時擁有實值和鍵值,pair的第一元素被視為鍵值,第二元素被視為實值,map不允許兩個元素有相同的鍵值。 我們可以通過map的迭代器改變map的鍵值嗎?答案是不行,因為map的鍵值關(guān)系到map元素的排列規(guī)則,任意改變map鍵值將會嚴(yán)重破壞map組織。如果想要修改元素的實值,那么是可以的。 Map和list擁有相同的某些性質(zhì),當(dāng)對它的容器元素進(jìn)行新增操作或者刪除操作時,操作之前的所有迭代器,在操作完成之后依然有效,當(dāng)然被刪除的那個元素的迭代器必然是個例外。 Multimap和map的操作類似,唯一區(qū)別multimap鍵值可重復(fù)。 Map和multimap都是以紅黑樹為底層實現(xiàn)機(jī)制。
2、map/multimap容器常用API
2.1構(gòu)造函數(shù)
map<T1, T2> mapTT;//map默認(rèn)構(gòu)造函數(shù): map(const map &mp);//拷貝構(gòu)造函數(shù)
2.2賦值操作函數(shù)
map& operator=(const map &mp);//重載等號操作符 swap(mp);//交換兩個集合容器
2.3大小操作函數(shù)
size();//返回容器中元素的數(shù)目 empty();//判斷容器是否為空
2.4插入數(shù)據(jù)元素操作
map.insert(...); //往容器插入元素,返回pair<iterator,bool>
map<int, string> mapStu;
// 第一種 通過pair的方式插入對象
mapStu.insert(pair<int, string>(3, "小張"));
// 第二種 通過pair的方式插入對象
mapStu.inset(make_pair(-1, "校長"));
// 第三種 通過value_type的方式插入對象
mapStu.insert(map<int, string>::value_type(1, "小李")); // 第四種 通過數(shù)組的方式插入值
mapStu[3] = "小劉";
mapStu[5] = "小王";
2.5刪除操作
clear();//刪除所有元素 erase(pos);//刪除pos迭代器所指的元素,返回下一個元素的迭代器。 erase(beg,end);//刪除區(qū)間[beg,end)的所有元素 ,返回下一個元素的迭代器。 erase(keyElem);//刪除容器中key為keyElem的對組。
2.6查找操作
find(key);//查找鍵key是否存在,若存在,返回該鍵的元素的迭代器;/若不存在,返回map.end(); count(keyElem);//返回容器中key為keyElem的對組個數(shù)。對map來說,要么是0,要么是1。對 multimap來說,值可能大于1。 lower_bound(keyElem);//返回第一個key>=keyElem元素的迭代器。 upper_bound(keyElem);//返回第一個key>keyElem元素的迭代器。 equal_range(keyElem);//返回容器中key與keyElem相等的上下限的兩個迭代器。
3、map應(yīng)用案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<map>
#include<string>
#include<vector>
#include <bits/stdc++.h>
using namespace std;
class Student
{
public:
string name;
int age;
public:
Student(){}
Student(string name, int age)
{
this->name = name;
this->age = age;
}
};
void test02()
{
map<int,Student> m;//存放學(xué)號 和 學(xué)員信息
vector<int> v;//存放學(xué)號
int i=0;
for(i=0;i<5; i++)
{
cout<<"請輸入學(xué)生的編號:";
int num;
cin>> num;
v.push_back(num);
cout<<"請輸入學(xué)生的信息:";
string name;
int age;
cin>>name>>age;
m.insert(make_pair(num,Student(name,age)));
}
//通過學(xué)號訪問學(xué)員信息
vector<int>::iterator it=v.begin();
for(;it != v.end(); it++)
{
//*it == num 學(xué)號
cout<<*it<<", "<<m[*it].name<<", "<<m[*it].age<<endl;
}
//抽簽(vector容器的內(nèi)容打亂)
random_shuffle(v.begin(), v.end());
cout<<"‐‐‐‐‐‐‐‐‐"<<endl;
it=v.begin();
for(;it != v.end(); it++)
{
//*it == num 學(xué)號
cout<<*it<<", "<<m[*it].name<<", "<<m[*it].age<<endl;
}
}
int main()
{
test02();
system("pause");
return EXIT_SUCCESS;
}
4、multimap應(yīng)用案例
公司今天招聘了5個員工,5名員工進(jìn)入公司之后,需要指派員工在那個部門工作 人員信息有: 姓名 年齡 電話 工資等組成 通過Multimap進(jìn)行信息的插入 保存 顯示 分部門顯示員工信息 顯示全部員工信息 。
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<map>#include<string>#include<vector>using namespace std;#define SALE_DEPATMENT 1 //銷售部門#define DEVELOP_DEPATMENT 2 //研發(fā)部門#define FINACIAL_DEPATMENT 3 //財務(wù)部門#define ALL_DEPATMENT 4 //所有部門//員工類class person{public:
string name; //員工姓名
int age; //員工年齡
double salary; //員工工資
string tele; //員工電話};//創(chuàng)建5個員工void CreatePerson(vector<person>& vlist){
string seed = "ABCDE";
for (int i = 0; i < 5; i++)
{
person p;
p.name = "員工";
p.name += seed[i];
p.age = rand() % 30 + 20;
p.salary = rand() % 20000 + 10000;
p.tele = "010-8888888";
vlist.push_back(p);
}}//5名員工分配到不同的部門void PersonByGroup(vector<person>& vlist, multimap<int, person>& plist){
int operate = -1; //用戶的操作
for (vector<person>::iterator it = vlist.begin(); it != vlist.end(); it++)
{
cout << "當(dāng)前員工信息:" << endl;
cout << "姓名:" << it->name << " 年齡:" << it->age << " 工資:" << it->salary << " 電話:" << it->tele << endl;
cout << "請對該員工進(jìn)行部門分配(1 銷售部門, 2 研發(fā)部門, 3 財務(wù)部門):" << endl; scanf("%d", &operate);
while (true)
{
if (operate == SALE_DEPATMENT){
//將該員工加入到銷售部門
plist.insert(make_pair(SALE_DEPATMENT, *it));
break;
}
else if (operate == DEVELOP_DEPATMENT)
{
plist.insert(make_pair(DEVELOP_DEPATMENT, *it));
break;
}
else if (operate == FINACIAL_DEPATMENT)
{
plist.insert(make_pair(FINACIAL_DEPATMENT, *it));
break;
}
else
{
cout << "您的輸入有誤,請重新輸入(1 銷售部門, 2 研發(fā)部門, 3 財務(wù)部門):" << endl;
scanf("%d", &operate);
}
}
}
cout << "員工部門分配完畢!" << endl;
cout << "***********************************************************" << endl;}//打印員工信息void printList(multimap<int, person>& plist, int myoperate){
if (myoperate == ALL_DEPATMENT)
{
for (multimap<int, person>::iterator it = plist.begin(); it != plist.end(); it++)
{
cout << "姓名:" << it->second.name << " 年齡:" << it->second.age << " 工資:" << it->second.salary << " 電話:" << it->second.tele << endl;
}
return;
}
multimap<int, person>::iterator it = plist.find(myoperate);
int depatCount = plist.count(myoperate);
int num = 0;
if (it != plist.end())
{
while (it != plist.end() && num < depatCount){
cout << "姓名:" << it->second.name << " 年齡:" << it->second.age << " 工資:" << it->second.salary << " 電話:" << it->second.tele << endl;
it++;
num++;
}
}}//根據(jù)用戶操作顯示不同部門的人員列表void ShowPersonList(multimap<int, person>& plist, int myoperate){
switch (myoperate)
{
case SALE_DEPATMENT: printList(plist, SALE_DEPATMENT);
break;
case DEVELOP_DEPATMENT: printList(plist, DEVELOP_DEPATMENT);
break;
case FINACIAL_DEPATMENT: printList(plist, FINACIAL_DEPATMENT);
break;
case ALL_DEPATMENT: printList(plist, ALL_DEPATMENT);
break;
}}//用戶操作菜單void PersonMenue(multimap<int, person>& plist){
int flag = -1;
int isexit = 0;
while (true)
{
cout << "請輸入您的操作((1 銷售部門, 2 研發(fā)部門, 3 財務(wù)部門, 4 所有部門, 0退 出):" << endl;
scanf("%d", &flag);
switch (flag)
{
case SALE_DEPATMENT: ShowPersonList(plist, SALE_DEPATMENT);
break;
case DEVELOP_DEPATMENT: ShowPersonList(plist, DEVELOP_DEPATMENT);
break;
case FINACIAL_DEPATMENT: ShowPersonList(plist, FINACIAL_DEPATMENT);
break;
case ALL_DEPATMENT: ShowPersonList(plist, ALL_DEPATMENT);
break;
case 0: isexit = 1;
break;
default: cout << "您的輸入有誤,請重新輸入!" << endl;
break;
}
if (isexit == 1)
{
break;
}
}}int main(){
vector<person> vlist;
//創(chuàng)建的5個員工 未分組
multimap<int, person> plist; //保存分組后員工信息 //創(chuàng)建5個員工
CreatePerson(vlist);
//5名員工分配到不同的部門
PersonByGroup(vlist, plist);
//根據(jù)用戶輸入顯示不同部門員工信息列表 或者 顯示全部員工的信息列表
PersonMenue(plist);
system("pause");
return EXIT_SUCCESS;}
5、容器總結(jié)
vector的使用場景:比如軟件歷史操作記錄的存儲
deque的使用場景:比如排隊購票系統(tǒng)
list的使用場景:支持頻繁的不確實位置元素的移除插入
set的使用場景:比如對手機(jī)游戲的個人得分記錄的存儲
map的使用場景:比如按ID號存儲十萬個用戶,想要快速要通過ID查找對應(yīng)的用戶。二叉樹的找效率,這時就體現(xiàn)出來了。
更多關(guān)于“智能物聯(lián)網(wǎng)培訓(xùn)”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學(xué),課程大綱緊跟企業(yè)需求,更科學(xué)更嚴(yán)謹(jǐn),每年培養(yǎng)泛IT人才近2萬人。不論你是零基礎(chǔ)還是想提升,都可以找到適合的班型,千鋒教育隨時歡迎你來試聽。