/*
*
********************************************
* map映照容器的基礎說明:
********************************************
*
* map映照容器:容器的數據結構採用紅黑樹進行管理,插入的元素鍵值不允許重複
* map的所有元素都是pair:第一元素爲鍵值(key),不能修改;第二元素爲實值(value),可被修改
*
* map和list一樣,使用insert或erase後,操作前的所有迭代器,在操作完成後依然有效
* []:不僅可用鍵值的數組方式訪問元素的映照數據,還可用來添加map容器的元素 //main中示例
*
* Sorted Associative Container Pair Associative Container Unique Associative Container
*
* 使用map必須使用宏語句#include <map>
*
**************************************************************************************
*
* 創建map對象:
* 1.map<char,int,greater<char> > a; //元素鍵值類型爲char,映照數據類型爲int,鍵值的比較函數對象爲greater<char>
* 2.map(const key_compare& comp) //指定一個比較函數對象comp來創建map對象
* 3.map(const map&); //map<int,char*> b(a); //此時使用默認的鍵值比較函數less<int>
* 4.map(first,last);
* 5.map(first,last,const key_compare& comp);
*
* //Example:
* pair<const int ,char> p1(1,'a');
* pair<const int ,char> p2(2,'b');
* pair<const int ,char> p3(3,'c');
* pair<const int ,char> p4(4,'d');
* pair<const int ,char> pairArray[]={p1,p2,p3,p4};
* map<const int,char> m4(pairArray,pairArray+5);
* map<const int,char> m3(m4);
* map<const int,char,greater<const int> > m5(pairArray,pairArray+5,greater<const int>());
*
**************************************************************************************
*
* 元素的插入
* //typedef pair<const key,T> value_type;
* pair<iterator,bool> insert(const value_type& v);
* iterator insert(iterator pos,const value_type& v);
* void insert(first,last);
*
**************************************************************************************
*
* 元素的刪除
* void erase(iterator pos);
* size_type erase(const key_type& k); //刪除等於鍵值k的元素
* void erase(first,last); //刪除[first,last)區間的元素
* void clear();
*
**************************************************************************************
*
* 訪問與搜索
*
* iterator begin();iterator end(); //企圖通過迭代器改變元素是不被允許的
* reverse_iterator rbegin();reverse_iterator rend();
*
* iterator find(const key_type& k) const;
* pair<iterator,iterator> equal_range(const key_type& k) const;//返回的pair對象,
* //first爲lower_bound(k);大於等於k的第一個元素位置
* //second爲upper_bound();大於k的第一個元素位置
*
* 其它常用函數
* bool empty() const;
* size_type size() const;
* void swap();
*
* iterator lower_bound();iterator upper_bound();pair<iterator,iterator> equal_range();//上界、下屆、確定區間
*
*
*
********************************************
** cumirror ** [email protected] ** **
********************************************
*
*/
#include <map>
#include <string>
#include <iostream>
// 基本操作與set類似,牢記map中所有元素都是pair
// 對於自定義類,初學者會覺得比較函數如何構造很麻煩,這個可以參照前面的書寫示例
// 但若設置鍵值爲int或char類型,無須構造比較函數
struct student{
char* name;
int age;
char* city;
char* phone;
};
struct strCmp{
bool operator () (const char* a,const char* b) const{
return strcmp(a,b)<0;
}
};
struct strCmpBig{
bool operator () (const char* a,const char* b) const{
return strcmp(a,b)>0;
}
};
int main(){
using namespace std;
// 使用[]操作符
map<string,int> animal;
animal[string("fish")]=12;
animal[string("dog")]=10;
animal[string("cat")]=5;
cout<<animal["cat"]<<endl;
// string類有默認的比較函數,故下面的語句可以執行,若換爲char*類型,則執行會出現問題
// 迭代器i指向pair類型
for(map<string,int>::iterator i=animal.begin();i!=animal.end();i++){
cout<<"The number of "<<i->first<<" : "<<i->second<<endl;
}
student s[]={
{"童進",23,"武漢","XXX"},
{"老大",23,"武漢","XXX"},
{"餃子",23,"武漢","XXX"}
};
pair<int,student> p1(4,s[0]);
pair<int,student> p2(2,s[1]);
pair<int,student> p3(3,s[2]);
map<int,student> a;
a.insert(p1);
a.insert(p2);
a.insert(p3);
// 按照鍵值2、3、4進行排列輸出
for(map<int,student>::iterator j=a.begin();j!=a.end();j++){
cout<<"The name: "<<j->second.name<<" "<<"age: "<<j->second.age<<" "
<<"city: "<<j->second.city<<" "<<"phone: "<<j->second.phone<<endl;
}
// 思考,這是按照鍵值進行排列,若我想變換,按照name或者年齡進行重新排列,那麼又該如何實現呢?
cout<<"新的排列"<<endl;
pair<const char*,student> q1(s[0].name,s[0]);
pair<const char*,student> q2(s[1].name,s[1]);
pair<const char*,student> q3(s[2].name,s[2]);
student testStu={"AB",23,"武漢","XXX"};
// 爲何要採用函數對象的形式,而不只能是函數,這個與C++內部實現機制有關
map<const char*,student,strCmp> b;
b.insert(q1);
b.insert(q2);
b.insert(q3);
// insert函數的測試,觀察其放回迭代器的值,可改變名字看看,插入位置視實際情況定
// 返回插入元素的迭代器
pair<const char*,student> q4(testStu.name,testStu);
map<const char*,student,strCmp>::iterator test=b.insert(b.begin()++,q4);
cout<<test->second.name<<endl;
for(map<const char*,student,strCmp>::iterator k=b.begin();k!=b.end();k++){
cout<<"The name: "<<k->second.name<<" "<<"age: "<<k->second.age<<" "
<<"city: "<<k->second.city<<" "<<"phone: "<<k->second.phone<<endl;
}
// 拷貝的時候也可以進行函數對象的設置,那如果函數對象變換了,能實現順序的變化嗎?
// 目前還沒實現,不知道具體可行嗎?以後再進行測試吧
// 個人觀點:不可行。函數對象比較的是key,若重新排列,key不能變換,
// 那麼所謂的重新排列,豈不僅僅是反序排列,而反序輸出map已經具有了這樣的函數了。
cout<<"拷貝時實現重新排列"<<endl; //並未實現
map<const char*,student,strCmp> c(b);
for(map<const char*,student,strCmp/*strCmpBig*/>::iterator m=c.begin();m!=c.end();m++){
cout<<"The name: "<<m->second.name<<" "<<"age: "<<m->second.age<<" "
<<"city: "<<m->second.city<<" "<<"phone: "<<m->second.phone<<endl;
}
return 0;
}