C++中最常用的容器用法與排序?qū)嵗?/h1>
更新時(shí)間:2021年08月31日 12:05:57 作者:陸嵩
C++ 中容器被定義為:在數(shù)據(jù)存儲(chǔ)上,有一種對象類型,它可以持有其它對象或指向其它對像的指針,這種對象類型就叫做容器,這篇文章主要給大家介紹了關(guān)于C++中最常用的容器用法與排序的相關(guān)資料,需要的朋友可以參考下
引述
C++ 的 STL 容器分為順序容器和關(guān)聯(lián)容器。
順序容器:vector、deque、list(forward_list)、array、string
關(guān)聯(lián)容器:map 和 set(及其 multi 和 無序版本)
容器適配器(不是容器):stack、queue、priority_queue
所謂的順序容器宏觀上理解就是小鬼們按一定的順序排排坐。關(guān)聯(lián)式包括類似于數(shù)據(jù)庫里面,有一個(gè) key,有一個(gè)值這樣的。只有順序容器的構(gòu)造函數(shù)才接受大小參數(shù),關(guān)聯(lián)容器并不支持。
順序容器的 at 和下標(biāo)操作值適用于 vector、string、deque、array。
容器那么多,操作那么雜,比如 array 不支持添加操作,forward_list 不支持 push_back,vector 和 string 不支持 push_front 等等,我也不住所有。既然如此,我們其實(shí)只要記一些關(guān)鍵容器的關(guān)鍵用法即可,其他等到需要的時(shí)候,百度查一查即可。下面,就是列出一些我們用得最多的容器的最最常用的一些操作和方法。
不考慮性能以及特殊數(shù)據(jù)結(jié)構(gòu)專有特性,一般 vector+map+set+string 可以打天下了。記那么多干嘛,年紀(jì)大了,根本記不住。如果非要留一個(gè),vector 其實(shí)也夠了。配上結(jié)構(gòu)體,什么都能干,操作麻煩一點(diǎn)性能差一點(diǎn)而已了。
vector
用法
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec;
vec.push_back(1);
vector<int> vec1;
vec1.resize(10);//10 個(gè) 0
vector<int> vec2(10);//10個(gè)元素,每個(gè)元素都是 0
vector<int> vec3(10, 1);//10 個(gè) 1
vec3.assign(10, 1);//分配 10 個(gè) 1
vector<int> vec4(vec3);
vec.size();
vec.empty();
vec.front();//返回一個(gè)元素,即迭代器start指向的元素
vec.back();
vector<int>::iterator it;
it = vec1.begin() + 5;
vec1.erase(it);//清除某個(gè)位置的元素
vec.clear();//清除所有的元素
it = find(vec3.begin(), vec3.end(), 10);//查找
sort(vec3.begin(), vec3.end());//vector沒有自帶排序方法,調(diào)用算法包,升序排序(默認(rèn))
sort(vec3.begin(), vec3.end(), less<int>());//升序排序
sort(vec3.begin(), vec3.end(), greater<int>());//降序排序
for (auto& it : vec) it++;//C++11 方式引用變量
vec3.capacity();獲取包括備用空間在內(nèi)的總?cè)萘看笮?
vec3.at(5);作用同上,增加異常處理,越界拋出out of range
vec3.max_size();//最大容量,即最多可以存儲(chǔ)多少個(gè)當(dāng)前類型元素
vec3.pop_back();//清除位于最后一個(gè)的元素
vec3.erase(vec3.begin(), vec3.end());
vec3.swap(vec2);
reverse(vec.begin(), vec.end());//元素翻轉(zhuǎn)
for (int i = 0; i < vec.size(); i++) cout << vec[i] << endl;
for (it = vec.begin(); it != vec.end(); it++) cout << *it << endl;
for (auto it : vec) cout << it << endl;
vector<int>::reverse_iterator rit;
for (rit = vec.rbegin(); rit != vec.rend(); rit++) cout << *rit << endl;
return 0;
}
其他說明
通常,使用 vecotr 是最好的選擇,除非你有很好的理由選擇其他容器。這也是我?guī)缀醪唤榻B其他順序容器的原因。什么時(shí)候不用 vector 呢?比如說,當(dāng)你基于性能的考慮,或者基于數(shù)據(jù)結(jié)構(gòu)典型用法的考慮。這里說的數(shù)據(jù)結(jié)構(gòu)典型性,指的是譬如你要寫的一個(gè)算法,用到了非常典型 “先進(jìn)后出” 的特征,而且有高強(qiáng)度的彈出和推入的操作,這時(shí)候你不妨考慮用 stack,而不是 vector。
在 vector 中間插入是合法但是是耗時(shí)的。很多人寫算法,想到哪個(gè)就用哪個(gè),這是很不對的,在選擇容器的時(shí)候,我們要考慮程序的性能。那么應(yīng)該如何選擇合適的容器呢?如果你想表達(dá)的數(shù)據(jù),stack 或者 queue 的特征已經(jīng)非常明顯了,直接用他倆;如果對數(shù)據(jù)后續(xù)要有大量的查找,就用關(guān)聯(lián)式容器,其中又以無序的查找最快,但是它無序;如果有大量的添加和刪除操作(特別是在中間),選擇 list,而盡可能地避免 vector 和 array;如果對元素的次序要求比較高,且沒有元素在中間的插入或者刪除,且沒有極其大量的查找,可以選擇 vector 和 array…
vector 其實(shí)也支持 insert 操作,但是因?yàn)橹虚g的插入對于 vector 來說是致命的耗時(shí),所以我們一般不這么干,不這么干,那就沒寫這個(gè)了。
map
用法
#include<iostream>
#include<map>
using namespace std;
int main() {
map<int, string> st;
st[0] = "str1";
st[1] = "str3";
st[2] = "str2";
st.insert(make_pair(3, "str3"));
st.insert(pair<int,string>(4, "str4"));
for (auto& it : st) cout << it.second << endl;
for (int i = 0; i < st.size(); i++) {//直接訪問
cout << st[i] << endl;
}
map<int, string>::iterator it = st.begin();//通過迭代器訪問
for (it;it != st.end(); it++) {
cout << it->first << " " << it->second << endl;
}
it = st.find(0);
cout << it->first << " " << it->second << endl;
st.erase(1);//通過鍵刪除
st.erase(st.find(0));//通過迭代器(指針)刪除
st.erase(st.begin(), st.end());//相當(dāng)于st.clear()
return 0;
}
其他說明
對一個(gè) map 使用下標(biāo)操作,其行為與數(shù)組或者 vector 上的下標(biāo)操作很不相同:使用一個(gè)不在容器中的關(guān)鍵字作為下標(biāo),會(huì)添加一個(gè)具有此關(guān)鍵字的元素到 map 中。
map 是插入元素的時(shí)候就已經(jīng)排好序了,當(dāng)你需要排好序的數(shù)據(jù)結(jié)構(gòu)的時(shí)候,可以考慮 map 和 set。
set
用法
#include<iostream>
#include<set>
using namespace std;
int main() {
set<int> s;
s.insert(3);
s.insert(5);
s.insert(1);
for (auto& it : s) cout << it << endl;
set<int>::iterator it;
for (it = s.begin();it != s.end(); it++) {
cout << *it<< endl;
}
s.erase(s.find(1));
s.erase(3);
s.erase(s.find(5), s.end());//刪除了5,9
s.clear();
cout << s.size();//輸出為
return 0;
}
其他說明
與 map 不同的地方,不能通過下標(biāo) key 來訪問了,只能直接 find。
string
#include<cstdio>
#include<string>
using namespace std;
int main() {
//增
string str1 = "abc";
string str2 = "def";
string str = str1 + str2;
str > str2;//字典序比較
str.insert(2, str1); //在下標(biāo)為 2 的地方插入str1
str.insert(str.begin() + 1, str1.begin(), str1.end());
//刪
str.erase(str.begin() + 1);
str.erase(str.begin() + 2, str.end());
str.erase(1, 2);//刪除從 1 開始的 2 個(gè)元素
//改
str.replace(0, 2, str1);//把起始位置為 0,長度為 2 的源子串替換為str1
str.replace(str.begin(), str.begin() + 2, str1);
//查(包括訪問)
int pos = str.find("bc");//返回查找字符串第一次在源串中的位置
pos = str.find("bc", 2);//從源串的第 2 個(gè)位開始查找, 返回在 str 中的下標(biāo)
for (auto& it : str) printf("%c\n", it);//
for (auto it = str.begin(); it < str.end(); it++) {
printf("%c\n", *it);
}
return 0;
}
用法
其他說明
string 和 vector 一樣,支持?jǐn)?shù)字下標(biāo)訪問。
直接讀入或者輸出一個(gè) string 類型,用 cin 和 cout。str[i] 要用 printf 輸出的。
總結(jié)
到此這篇關(guān)于C++中最常用的容器用法與排序的文章就介紹到這了,更多相關(guān)C++容器用法與排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
淺析內(nèi)存對齊與ANSI C中struct型數(shù)據(jù)的內(nèi)存布局
當(dāng)在C中定義了一個(gè)結(jié)構(gòu)類型時(shí),它的大小是否等于各字段(field)大小之和?編譯器將如何在內(nèi)存中放置這些字段?ANSI C對結(jié)構(gòu)體的內(nèi)存布局有什么要求?而我們的程序又能否依賴這種布局 2013-09-09
-
C語言動(dòng)態(tài)內(nèi)存函數(shù)詳解
這篇文章主要介紹了C語言動(dòng)態(tài)內(nèi)存函數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧 2021-09-09
-
C語言之實(shí)現(xiàn)控制臺光標(biāo)隨意移動(dòng)的實(shí)例代碼
下面小編就為大家?guī)硪黄狢語言之實(shí)現(xiàn)控制臺光標(biāo)隨意移動(dòng)的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧 2016-07-07
-
C++ 析構(gòu)函數(shù)與變量的生存周期實(shí)例詳解
這篇文章主要介紹了C++ 析構(gòu)函數(shù)與變量的生存周期實(shí)例詳解的相關(guān)資料 2017-06-06
-
C語言中求余弦值的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語言中求余弦值的相關(guān)函數(shù)總結(jié),包括求余弦和雙曲線余弦以及反余弦的求值,需要的朋友可以參考下 2015-08-08
-
關(guān)于虛函數(shù)實(shí)現(xiàn)多態(tài)的原理及分析
這篇文章主要介紹了C++中如何實(shí)現(xiàn)多態(tài)問題,具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2023-02-02
最新評論
引述
C++ 的 STL 容器分為順序容器和關(guān)聯(lián)容器。
順序容器:vector、deque、list(forward_list)、array、string
關(guān)聯(lián)容器:map 和 set(及其 multi 和 無序版本)
容器適配器(不是容器):stack、queue、priority_queue
所謂的順序容器宏觀上理解就是小鬼們按一定的順序排排坐。關(guān)聯(lián)式包括類似于數(shù)據(jù)庫里面,有一個(gè) key,有一個(gè)值這樣的。只有順序容器的構(gòu)造函數(shù)才接受大小參數(shù),關(guān)聯(lián)容器并不支持。
順序容器的 at 和下標(biāo)操作值適用于 vector、string、deque、array。
容器那么多,操作那么雜,比如 array 不支持添加操作,forward_list 不支持 push_back,vector 和 string 不支持 push_front 等等,我也不住所有。既然如此,我們其實(shí)只要記一些關(guān)鍵容器的關(guān)鍵用法即可,其他等到需要的時(shí)候,百度查一查即可。下面,就是列出一些我們用得最多的容器的最最常用的一些操作和方法。
不考慮性能以及特殊數(shù)據(jù)結(jié)構(gòu)專有特性,一般 vector+map+set+string 可以打天下了。記那么多干嘛,年紀(jì)大了,根本記不住。如果非要留一個(gè),vector 其實(shí)也夠了。配上結(jié)構(gòu)體,什么都能干,操作麻煩一點(diǎn)性能差一點(diǎn)而已了。
vector
用法
#include<iostream> #include<vector> #include <algorithm> using namespace std; int main() { vector<int> vec; vec.push_back(1); vector<int> vec1; vec1.resize(10);//10 個(gè) 0 vector<int> vec2(10);//10個(gè)元素,每個(gè)元素都是 0 vector<int> vec3(10, 1);//10 個(gè) 1 vec3.assign(10, 1);//分配 10 個(gè) 1 vector<int> vec4(vec3); vec.size(); vec.empty(); vec.front();//返回一個(gè)元素,即迭代器start指向的元素 vec.back(); vector<int>::iterator it; it = vec1.begin() + 5; vec1.erase(it);//清除某個(gè)位置的元素 vec.clear();//清除所有的元素 it = find(vec3.begin(), vec3.end(), 10);//查找 sort(vec3.begin(), vec3.end());//vector沒有自帶排序方法,調(diào)用算法包,升序排序(默認(rèn)) sort(vec3.begin(), vec3.end(), less<int>());//升序排序 sort(vec3.begin(), vec3.end(), greater<int>());//降序排序 for (auto& it : vec) it++;//C++11 方式引用變量 vec3.capacity();獲取包括備用空間在內(nèi)的總?cè)萘看笮? vec3.at(5);作用同上,增加異常處理,越界拋出out of range vec3.max_size();//最大容量,即最多可以存儲(chǔ)多少個(gè)當(dāng)前類型元素 vec3.pop_back();//清除位于最后一個(gè)的元素 vec3.erase(vec3.begin(), vec3.end()); vec3.swap(vec2); reverse(vec.begin(), vec.end());//元素翻轉(zhuǎn) for (int i = 0; i < vec.size(); i++) cout << vec[i] << endl; for (it = vec.begin(); it != vec.end(); it++) cout << *it << endl; for (auto it : vec) cout << it << endl; vector<int>::reverse_iterator rit; for (rit = vec.rbegin(); rit != vec.rend(); rit++) cout << *rit << endl; return 0; }
其他說明
通常,使用 vecotr 是最好的選擇,除非你有很好的理由選擇其他容器。這也是我?guī)缀醪唤榻B其他順序容器的原因。什么時(shí)候不用 vector 呢?比如說,當(dāng)你基于性能的考慮,或者基于數(shù)據(jù)結(jié)構(gòu)典型用法的考慮。這里說的數(shù)據(jù)結(jié)構(gòu)典型性,指的是譬如你要寫的一個(gè)算法,用到了非常典型 “先進(jìn)后出” 的特征,而且有高強(qiáng)度的彈出和推入的操作,這時(shí)候你不妨考慮用 stack,而不是 vector。
在 vector 中間插入是合法但是是耗時(shí)的。很多人寫算法,想到哪個(gè)就用哪個(gè),這是很不對的,在選擇容器的時(shí)候,我們要考慮程序的性能。那么應(yīng)該如何選擇合適的容器呢?如果你想表達(dá)的數(shù)據(jù),stack 或者 queue 的特征已經(jīng)非常明顯了,直接用他倆;如果對數(shù)據(jù)后續(xù)要有大量的查找,就用關(guān)聯(lián)式容器,其中又以無序的查找最快,但是它無序;如果有大量的添加和刪除操作(特別是在中間),選擇 list,而盡可能地避免 vector 和 array;如果對元素的次序要求比較高,且沒有元素在中間的插入或者刪除,且沒有極其大量的查找,可以選擇 vector 和 array…
vector 其實(shí)也支持 insert 操作,但是因?yàn)橹虚g的插入對于 vector 來說是致命的耗時(shí),所以我們一般不這么干,不這么干,那就沒寫這個(gè)了。
map
用法
#include<iostream> #include<map> using namespace std; int main() { map<int, string> st; st[0] = "str1"; st[1] = "str3"; st[2] = "str2"; st.insert(make_pair(3, "str3")); st.insert(pair<int,string>(4, "str4")); for (auto& it : st) cout << it.second << endl; for (int i = 0; i < st.size(); i++) {//直接訪問 cout << st[i] << endl; } map<int, string>::iterator it = st.begin();//通過迭代器訪問 for (it;it != st.end(); it++) { cout << it->first << " " << it->second << endl; } it = st.find(0); cout << it->first << " " << it->second << endl; st.erase(1);//通過鍵刪除 st.erase(st.find(0));//通過迭代器(指針)刪除 st.erase(st.begin(), st.end());//相當(dāng)于st.clear() return 0; }
其他說明
對一個(gè) map 使用下標(biāo)操作,其行為與數(shù)組或者 vector 上的下標(biāo)操作很不相同:使用一個(gè)不在容器中的關(guān)鍵字作為下標(biāo),會(huì)添加一個(gè)具有此關(guān)鍵字的元素到 map 中。
map 是插入元素的時(shí)候就已經(jīng)排好序了,當(dāng)你需要排好序的數(shù)據(jù)結(jié)構(gòu)的時(shí)候,可以考慮 map 和 set。
set
用法
#include<iostream> #include<set> using namespace std; int main() { set<int> s; s.insert(3); s.insert(5); s.insert(1); for (auto& it : s) cout << it << endl; set<int>::iterator it; for (it = s.begin();it != s.end(); it++) { cout << *it<< endl; } s.erase(s.find(1)); s.erase(3); s.erase(s.find(5), s.end());//刪除了5,9 s.clear(); cout << s.size();//輸出為 return 0; }
其他說明
與 map 不同的地方,不能通過下標(biāo) key 來訪問了,只能直接 find。
string
#include<cstdio> #include<string> using namespace std; int main() { //增 string str1 = "abc"; string str2 = "def"; string str = str1 + str2; str > str2;//字典序比較 str.insert(2, str1); //在下標(biāo)為 2 的地方插入str1 str.insert(str.begin() + 1, str1.begin(), str1.end()); //刪 str.erase(str.begin() + 1); str.erase(str.begin() + 2, str.end()); str.erase(1, 2);//刪除從 1 開始的 2 個(gè)元素 //改 str.replace(0, 2, str1);//把起始位置為 0,長度為 2 的源子串替換為str1 str.replace(str.begin(), str.begin() + 2, str1); //查(包括訪問) int pos = str.find("bc");//返回查找字符串第一次在源串中的位置 pos = str.find("bc", 2);//從源串的第 2 個(gè)位開始查找, 返回在 str 中的下標(biāo) for (auto& it : str) printf("%c\n", it);// for (auto it = str.begin(); it < str.end(); it++) { printf("%c\n", *it); } return 0; }
用法
其他說明
string 和 vector 一樣,支持?jǐn)?shù)字下標(biāo)訪問。
直接讀入或者輸出一個(gè) string 類型,用 cin 和 cout。str[i] 要用 printf 輸出的。
總結(jié)
到此這篇關(guān)于C++中最常用的容器用法與排序的文章就介紹到這了,更多相關(guān)C++容器用法與排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析內(nèi)存對齊與ANSI C中struct型數(shù)據(jù)的內(nèi)存布局
當(dāng)在C中定義了一個(gè)結(jié)構(gòu)類型時(shí),它的大小是否等于各字段(field)大小之和?編譯器將如何在內(nèi)存中放置這些字段?ANSI C對結(jié)構(gòu)體的內(nèi)存布局有什么要求?而我們的程序又能否依賴這種布局2013-09-09C語言動(dòng)態(tài)內(nèi)存函數(shù)詳解
這篇文章主要介紹了C語言動(dòng)態(tài)內(nèi)存函數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-09-09C語言之實(shí)現(xiàn)控制臺光標(biāo)隨意移動(dòng)的實(shí)例代碼
下面小編就為大家?guī)硪黄狢語言之實(shí)現(xiàn)控制臺光標(biāo)隨意移動(dòng)的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07C++ 析構(gòu)函數(shù)與變量的生存周期實(shí)例詳解
這篇文章主要介紹了C++ 析構(gòu)函數(shù)與變量的生存周期實(shí)例詳解的相關(guān)資料2017-06-06C語言中求余弦值的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語言中求余弦值的相關(guān)函數(shù)總結(jié),包括求余弦和雙曲線余弦以及反余弦的求值,需要的朋友可以參考下2015-08-08關(guān)于虛函數(shù)實(shí)現(xiàn)多態(tài)的原理及分析
這篇文章主要介紹了C++中如何實(shí)現(xiàn)多態(tài)問題,具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02