C++ 最常用的容器最常用法與排序(持續增刪改)
文章目錄
- C++ 最常用的容器最常用法與排序(持續增刪改)
- 引述
- vector
- 用法
- 其他說明
- map
- 用法
- 其他說明
- set
- 用法
- 其他說明
- string
- 用法
- 其他說明
引述
C++ 的 STL 容器分為順序容器和關聯容器,
順序容器:vector、deque、list(forward_list)、array、string
關聯容器:map 和 set(及其 multi 和 無序版本)
容器配接器(不是容器):stack、queue、priority_queue
所謂的順序容器宏觀上理解就是小鬼們按一定的順序排排坐,關聯式包括類似于資料庫里面,有一個 key,有一個值這樣的,只有順序容器的建構式才接受大小引數,關聯容器并不支持,
順序容器的 at 和下標操作值適用于 vector、string、deque、array,
容器那么多,操作那么雜,比如 array 不支持添加操作,forward_list 不支持 push_back,vector 和 string 不支持 push_front 等等,我也不住所有,既然如此,我們其實只要記一些關鍵容器的關鍵用法即可,其他等到需要的時候,百度查一查即可,下面,就是列出一些我們用得最多的容器的最最常用的一些操作和方法,
不考慮性能以及特殊資料結構專有特性,一般 vector+map+set+string 可以打天下了,記那么多干嘛,年紀大了,根本記不住,如果非要留一個,vector 其實也夠了,配上結構體,什么都能干,操作麻煩一點性能差一點而已了,
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 個 0
vector<int> vec2(10);//10個元素,每個元素都是 0
vector<int> vec3(10, 1);//10 個 1
vec3.assign(10, 1);//分配 10 個 1
vector<int> vec4(vec3);
vec.size();
vec.empty();
vec.front();//回傳一個元素,即迭代器start指向的元素
vec.back();
vector<int>::iterator it;
it = vec1.begin() + 5;
vec1.erase(it);//清除某個位置的元素
vec.clear();//清除所有的元素
it = find(vec3.begin(), vec3.end(), 10);//查找
sort(vec3.begin(), vec3.end());//vector沒有自帶排序方法,呼叫演算法包,升序排序(默認)
sort(vec3.begin(), vec3.end(), less<int>());//升序排序
sort(vec3.begin(), vec3.end(), greater<int>());//降序排序
for (auto& it : vec) it++;//C++11 方式參考變數
vec3.capacity();獲取包括備用空間在內的總容量大小
vec3.at(5);作用同上,增加例外處理,越界拋出out of range
vec3.max_size();//最大容量,即最多可以存盤多少個當前型別元素
vec3.pop_back();//清除位于最后一個的元素
vec3.erase(vec3.begin(), vec3.end());
vec3.swap(vec2);
reverse(vec.begin(), vec.end());//元素翻轉
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 是最好的選擇,除非你有很好的理由選擇其他容器,這也是我幾乎不介紹其他順序容器的原因,什么時候不用 vector 呢?比如說,當你基于性能的考慮,或者基于資料結構典型用法的考慮,這里說的資料結構典型性,指的是譬如你要寫的一個演算法,用到了非常典型 “先進后出” 的特征,而且有高強度的彈出和推入的操作,這時候你不妨考慮用 stack,而不是 vector,
在 vector 中間插入是合法但是是耗時的,很多人寫演算法,想到哪個就用哪個,這是很不對的,在選擇容器的時候,我們要考慮程式的性能,那么應該如何選擇合適的容器呢?如果你想表達的資料,stack 或者 queue 的特征已經非常明顯了,直接用他倆;如果對資料后續要有大量的查找,就用關聯式容器,其中又以無序的查找最快,但是它無序;如果有大量的添加和洗掉操作(特別是在中間),選擇 list,而盡可能地避免 vector 和 array;如果對元素的次序要求比較高,且沒有元素在中間的插入或者洗掉,且沒有極其大量的查找,可以選擇 vector 和 array…
vector 其實也支持 insert 操作,但是因為中間的插入對于 vector 來說是致命的耗時,所以我們一般不這么干,不這么干,那就沒寫這個了,
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());//相當于st.clear()
return 0;
}
其他說明
對一個 map 使用下標操作,其行為與陣列或者 vector 上的下標操作很不相同:使用一個不在容器中的關鍵字作為下標,會添加一個具有此關鍵字的元素到 map 中,
map 是插入元素的時候就已經排好序了,當你需要排好序的資料結構的時候,可以考慮 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 不同的地方,不能通過下標 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); //在下標為 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 個元素
//改
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 個位開始查找, 回傳在 str 中的下標
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 一樣,支持數字下標訪問,
直接讀入或者輸出一個 string 型別,用 cin 和 cout,str[i] 要用 printf 輸出的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296588.html
標籤:其他
