[c++] Associative Containers

關聯容器 和 順序容器 的本質差異在於: html

關聯容器經過鍵(key)存儲和讀取元素,而順序容器則經過元素在容器中的位置順序存儲和訪問元素。ios

Reference: http://www.cnblogs.com/kingcat/archive/2012/05/11/2496135.htmlc++

  

關聯式容器依據特定的排序準則,自動爲其元素排序。排序準則以函數形式呈現,用來比較元素值(value)或元素鍵(key)。缺省狀況下以operator<進行 比較,不過你也能夠提供本身的比較函數,定義出不一樣的排序準則。數組

一般關聯式容器由二叉樹(binary tree)實現。在二叉樹中,每一個元素(節 點)都有一個父節點和兩個子節點;左子樹的全部元素都比本身小,右子樹的全部元素都比本身大。關聯式容器的差異主要在於元素的類型以及處理重複元素時的方式。數據結構

STL預先定義好的關聯式容器有:集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。less

 

  

關聯容器類型

map函數

關聯數組:元素經過鍵來存儲和讀取this

setspa

大小可變的集合,支持經過鍵實現的快速讀取.net

multimap

支持同一個鍵屢次出現的 map 類型

multiset

支持同一個鍵屢次出現的 set 類型

 

 

 

 

 

 

 

 

 

 

Map 操做

int main() { cout << "Hello World!" << endl; pair<string, int> author; author.first = "lolo"; author.second = 18; pair<string, int> author2; author2 = make_pair("lolo", 18); map<string, int>myMap; myMap["jeff"] = 29; cout << myMap["jeff"] << endl; cout << myMap["lolo"] << endl;  //Actually, new element added.

    return 0; }

 

默認添加「被搜索的」空鍵值

查找Key不存在的內容,會默認自動添加。

    1. The map contains this key. So it will return the corresponding key value.
    2. The map doesn't contain the key. In this case, it will automatically add a key to the map with null value.

 

查找鍵值

找到第一個就返回了。

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}

 

計數鍵值

須要整個遍歷一遍。

if (m.count("f")>0)
      cout << " is an element of m.\n";
    else 
      cout << " is not an element of m.\n";

 

 

默認 key 排序 - 相似Max/Min heap

#include<map> #include<string> #include<iostream>  
using namespace std; typedef pair<string, int> PAIR; ostream& operator<<(ostream& out, const PAIR& p) { return out << p.first << "\t" << p.second; } int main() { map<string, int, greater<string>> name_score_map; 
name_score_map[
"LiMin"] = 90; name_score_map["ZiLinMi"] = 79; name_score_map["BoB"] = 92; name_score_map.insert(make_pair("Bing",99)); name_score_map.insert(make_pair("Albert",86));
for (map<string, int>::iterator iter = name_score_map.begin(); iter != name_score_map.end(); ++iter) { cout << *iter << endl; }
return 0
; }

 

自定義 key 排序

structCmpByKeyLength { bool operator()(const string& k1, const string& k2) { return k1.length() < k2.length(); } }; // 使用了函數類 int main() { 
map
<string, int, CmpByKeyLength> name_score_map; name_score_map["LiMin"] = 90; name_score_map["ZiLinMi"] = 79; name_score_map["BoB"] = 92; name_score_map.insert(make_pair("Bing",99)); name_score_map.insert(make_pair("Albert",86));
for (map<string, int>::iterator iter = name_score_map.begin(); iter != name_score_map.end(); ++iter) { cout << *iter << endl; }
return 0
; }

 

 

Set

void func_set(void) { std::set<int> myset; std::set<int>::iterator it; std::pair<std::set<int>::iterator, bool> ret; // set some initial values:
      for (int i=1; i<=5; ++i) {
myset.insert(i*10); // set: 10 20 30 40 50
}

// Jeff --> ret.second 插入成功? 原來沒有;插入失敗?本來就有。 ret = myset.insert(20); if (ret.second==false) {
it=ret.first; // "it" now points to element 20 }

myset.insert (it, 25); // max efficiency inserting myset.insert (it, 24); // max efficiency inserting myset.insert (it, 26); // no max efficiency inserting int myints[]= {5,10,15}; // 10 already in set, not inserted myset.insert (myints,myints+3); std::cout << "myset contains:"; for (it=myset.begin(); it!=myset.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; }

 

c++之stl 二叉樹

set由二叉搜索樹實現,而且對樹進行了平衡處理,使得元素在樹中分部較爲均勻,所以能保持搜索、插入、刪除的複雜度在O(logn)。

 

multimap

How is it useful: Multimaps are one of those things that you need rarely, but when you need them, you really need them.

 1 /*
 2  *  3  ********************************************  4  * multimap多重映照容器的基礎說明:  5  ********************************************  6  *  7  * multimap多重映照容器:容器的數據結構採用紅黑樹進行管理  8  * multimap的全部元素都是pair:第一元素爲鍵值(key),不能修改;第二元素爲實值(value),可被修改  9  *  10  * multimap特性以及用法與map徹底相同,惟一的差異在於:  11  * 容許重複鍵值的元素插入容器(使用了RB-Tree的insert_equal函數)  12  * 所以:  13  * 鍵值key與元素value的映照關係是多對多的關係  14  * 沒有定義[]操做運算  15  *  16  * Sorted Associative Container Pair Associative Container Unique Associative Container  17  *  18  * 使用multimap必須使用宏語句#include <map>  19  *  20  **************************************************************************************  21  *  22  * 建立multimap對象:  23  * 1.multimap<char,int,greater<char> > a; //元素鍵值類型爲char,映照數據類型爲int,鍵值的比較函數對象爲greater<char>  24  * 2.multimap(const key_compare& comp) //指定一個比較函數對象comp來建立map對象  25  * 3.multimap(const multisetr&); //multimap<int,char*> b(a); //此時使用默認的鍵值比較函數less<int>  26  * 4.multimap(first,last);  27  * 5.multimap(first,last,const key_compare& comp);  28  *  29  * //Example:  30  * pair<const int ,char> p1(1,'a');  31  * pair<const int ,char> p2(2,'b');  32  * pair<const int ,char> p3(3,'c');  33  * pair<const int ,char> p4(4,'d');  34  * pair<const int ,char> pairArray[]={p1,p2,p3,p4};  35  * multimap<const int,char> m4(pairArray,pairArray+5);  36  * multimap<const int,char> m3(m4);  37  * multimap<const int,char,greater<const int> > m5(pairArray,pairArray+5,greater<const int>());  38  *  39  **************************************************************************************  40  *  41  * 元素的插入  42  * //typedef pair<const key,T> value_type;  43  * pair<iterator,bool> insert(const value_type& v);  44  * iterator insert(iterator pos,const value_type& v);  45  * void insert(first,last);  46  *  47  **************************************************************************************  48  *  49  * 元素的刪除  50  * void erase(iterator pos);  51  * size_type erase(const key_type& k); //刪除等於鍵值k的元素  52  * void erase(first,last); //刪除[first,last)區間的元素  53  * void clear();  54  *  55  **************************************************************************************  56  *  57  * 訪問與搜索  58  *  59  * iterator begin();iterator end(); //企圖經過迭代器改變元素是不被容許的  60  * reverse_iterator rbegin();reverse_iterator rend();  61  *  62  * iterator find(const key_type& k) const;  63  * pair<iterator,iterator> equal_range(const key_type& k) const;//返回的pair對象,  64  * //first爲lower_bound(k);大於等於k的第一個元素位置  65  * //second爲upper_bound();大於k的第一個元素位置  66  *  67  * 其它經常使用函數  68  * bool empty() const;  69  * size_type size() const;  70  * size_type count(const key_type& k) const; //返回鍵值等於k的元素個數  71  * void swap();  72  *  73  * iterator lower_bound();iterator upper_bound();pair<iterator,iterator> equal_range();//上界、下屆、肯定區間  74  *  75  *  76  *  77  ********************************************  78  ** cumirror ** tongjinooo@163.com ** **  79  ********************************************  80  *  81  */
 82 
 83 #include <map>
 84 #include <string>
 85 #include <iostream>
 86 
 87 // 基本操做與set類型,牢記map中全部元素都是pair  88 // 對於自定義類,初學者會以爲比較函數如何構造很麻煩,這個能夠參照前面的書寫示例  89 // 但若設置鍵值爲int或char類型,無須構造比較函數
 90 
 91 struct student{  92  char* name;  93  int age;  94  char* city;  95  char* phone;  96 };  97 
 98 int main()  99 { 100      using namespace std; 101 
102      student s[]={ 103       {"童進",23,"武漢","XXX"}, 104       {"老大",23,"武漢","XXX"}, 105       {"餃子",23,"武漢","XXX"}, 106       {"王老虎",23,"武漢","XXX"}, 107       {"周潤發",23,"武漢","XXX"}, 108       {"周星星",23,"武漢","XXX"} 109  }; 110       pair<int,student> p1(4,s[0]); 111       pair<int,student> p2(2,s[1]); 112       pair<int,student> p3(3,s[2]); 113       pair<int,student> p4(4,s[3]);  //鍵值key與p1相同
114       pair<int,student> p5(5,s[4]); 115       pair<int,student> p6(6,s[5]); 116      multimap<int, student> a; 117  a.insert(p1); 118  a.insert(p2); 119  a.insert(p3); 120  a.insert(p4); 121  a.insert(p5); 122  a.insert(p6); // 會有重複的key 123      typedef multimap<int, student>::iterator int_multimap; 124      pair<int_multimap,int_multimap> p = a.equal_range(4); 125      int_multimap i = a.find(4); 126      cout<<"班上key值爲"<< i->first<<"的學生有:"<<a.count(4)<<"名,"<<" 他們是:"<<endl; 127      for(int_multimap k = p.first; k != p.second; k++) 128  { 129         cout<<k->second.name<<endl; 130  } 131      cout<<"刪除重複鍵值的同窗"<<endl; 132  a.erase(i); 133      cout<<"如今班上總人數爲:"<<a.size()<<". 人員以下:"<<endl; 134      for(multimap<int,student>::iterator j=a.begin(); j != a.end(); j++) 135  { 136           cout<<"The name: "<<j->second.name<<"      "<<"age: "<<j->second.age<<"   "
137            <<"city: "<<j->second.city<<"      "<<"phone: "<<j->second.phone<<endl; 138  } 139 
140      return 0; 141 }
相關文章
相關標籤/搜索