1. 程式人生 > 其它 >【Black_Panda】STL-map和set

【Black_Panda】STL-map和set

map(對映)

  • \(map\) 是更強大的陣列。
  • 之所以說它強大,有兩點原因:
    • 第一,\(map\) 可以當作陣列使用,但下標不僅侷限於數字。
    • 第二,\(map\) 的內部元素是\(\color{#ff0000}{\text{有序}}\)的。

1.定義

  • \(map\) 又被稱為對映,是從 \(key\)\(value\) 的對映,給定 \(key\) 就能確定 \(value\)
  • 實際上陣列也可以看作是從 \(key\)\(value\) 的對映,其中 \(key\) 是整數下標,\(value\) 是陣列中儲存的值
  • 要定義一個 \(map\),就要指明 \(key\)
    \(value\) 的資料型別,定義格式如下:
    • map<key_t,value_t>名字;
    • 例如:map<string,double>sd;

2.map的使用

  • \(map\) 可以像陣列一樣進行呼叫、賦值。
#include <bits/stdc++.h>
using namespace std;
map<string,double>f;
int main(){
    f["nihao"]=3.1415926;
    cout<<f["nihao"]<<endl;
    f["byebye"]=666.789;
    cout<<f["byebye"]<<endl;
}

3.迭代器

  • 它是用來遍歷的,在 \(STL\) 的容器中如 vector、map、set 中我們經常要用迭代器去遍歷其中的元素,尤其是在 \(map\)\(set\) 中。
  • 定義:map<key_t,value_t>::iterator 迭代器名;
  • 首先定義一個 map<string,double> 的迭代器
    • 例如:map<string,double>::iterator it;

4.map中的元素——pair

  • \(map\) 中,儲存的元素有 \(key\)\(value\),對應的是 \(STL\) 中的 \(pair\)
    型別。
  • \(pair\) 型別可以單獨定義。
  • pair<key_t,value_t>變數名;
  • 它可以理解為含有兩個變數 \(first\)\(second\) 的結構體。
  • \(\color{#ff0000}{\text{初始化方法:}}\) pair<key_t,value_t>(key,value)
#include <bits/stdc++.h>
using namespace std;
pair<int,int>p;
int main(){
    p=pair<int,int>(1,1);
    cout<<p.first<<" "<<p.second;
    return 0;
}

5.迭代器遍歷

  • 迭代器像指標一樣,可以用 -> 符號取出元素。
  • 迭代器是 \(pair\) 的指標,對應有兩個元素。
  • it->first\(key\)it->second\(value\)
  • f.begin()\(f\) 開頭對應的迭代器,f.end()\(f\) 結尾位置對應的迭代器(但結尾是沒有元素的)。
#include <bits/stdc++.h>
using namespace std;
map<string,double>f;
map<string,double>::iterator it;
int main(){
    f["nihao"]=3.1415926;
    cout<<f["nihao"]<<endl;
    f["byebye"]=666.789;
    cout<<f["byebye"]<<endl;
    for(it=f.begin();it!=f.end();it++)
        cout<<(it->first)<<" "<<(it->second);
}
  • \(map\) 中,所有元素是 \(\color{#ff0000}{\text{按}key\text{從小到大排列}}\) 的。
  • 我們用迭代器進行遍歷時,遍歷到的元素的 \(key\) 也是從小到大的。

6.查詢map中的元素

  • 使用下列方法查詢 \(map\) 中是否有 \(key\) 對應的 \(value\)
  • .find(key);
  • 返回值:如果存在,返回元素對應的迭代器,否則返回 .end()
  • 判斷一個鍵是否存在的方法如下:
if(f.find("byebye") != f.end()){
    //存在
}
else{
    //不存在
}
  • 在不確定 \(map\) 中存在 \(key\) 對應的 \(value\) 時,必須使用 \(find\) 先查詢,否則如果直接使用下標索引,會導致執行時錯誤!(和陣列下標越界類似)

set

  • \(set\),顧名思義,是一個集合,
  • 在 C++ 中,\(set\) 是一個\(\color{#ff0000}{\text{有序集合}}\),其內的元素是按\(\color{#ff0000}{\text{從小到大}}\)的順序排好序的。

1.定義

  • 在定義一個 \(set\) 時,要指明這個集合中的元素的資料型別。

  • 定義格式為:set<資料型別>名字;

  • 例如,如果我們維護一個整數的有序序列,名為 \(S\)

    set<int> S;

  • 集合必須是不

2.元素的插入

將一個數據插入到集合中,需要呼叫函式 .insert()

#include <bits/stdc++.h>
using namespace std;
set<int>S;
int main(){
	S.insert(10);
	S.insert(6);
	S.insert(9);
}

3.set的遍歷

  • \(map\) 類似,遍歷 \(set\) 中的元素需要用到迭代器。
  • 每個迭代器指向 \(set\) 中的一個元素,用 *可以取出對應的資料。
#include <bits/stdc++.h>
using namespace std;
set<int>S;
set<int>::iterator it;
int main(){
	S.insert(10);
	S.insert(6);
	S.insert(9);
    for(it=S.begin();it!=S.end();it++)
    	cout<<*it<<endl;
}

4.multiset

  • 當我們需要統計\(\color{#ff0000}{\text{重複}}\)元素時,我們可以使用”另一個版本“:multiset
  • 定義格式為:```multiset<資料型別>名字;``
  • 例如,如果我們需要維護一個整數的有序可重複集合,名為MS:

multiset<int>MS;(在其他方面,例如函式和迭代器,multiset均與set用法一致)

5.查詢set中的元素

  • 使用下列方法查詢 \(set\) 中是否有某個元素。
  • .find(值)
  • 返回值:如果存在,返回元素對應的迭代器,否則返回 .end()
  • 判斷一個鍵是否存在:
if(s.find(1000) != s.end()){
    //存在
}
else{
 	//不存在   
}
  • \(set\) 中,由於元素不可重複,一旦找到,個數一定為 \(1\)

6.查詢multiset中的元素

  • 因為 \(multiset\) 是可重集合,怎麼才能確定等於 \(key\) 的元素有多少個呢
  • 使用下面的方法統計等於 \(key\) 的元素的個數:

.count(key)

7.map和set小結

  • \(map\) 是鍵值對,和陣列一樣,有鍵值對對映時使用。
  • \(set\) 是不可重集合,可以自動去重。
  • 如果想要有重複元素,可換用 \(multiset\)
  • \(map\)\(set\) 都是保持有序的,都可以用迭代器遍歷。
  • \(STL\) 的使用不侷限於課件上的內容,可以利用搜索引擎學習更多 \(STL\) 的方法。