C++ STL序列式容器
序列式容器
vector list deque
0. 迭代器
前向迭代器
支援++p,*p等操作
雙向迭代器
支援--p等操作哦
隨機訪問迭代器
p+=i 迭代器往後移動i個元素
p+i 返回迭代器後第i個元素的迭代器
p[i] 返回p後面第i個元素的引用
迭代器定義方式 | 具體格式 |
---|---|
正向迭代器 | 容器類名::iterator 迭代器名; |
常量正向迭代器 | 容器類名::const_iterator 迭代器名; |
反向迭代器 | 容器類名::reverse_iterator 迭代器名; |
常量反向迭代器 | 容器類名::const_reverse_iterator 迭代器名; |
通過迭代器遍歷
for(i=v.begin();i<v.end();++i){
cout<<*i<<endl;
}
array<T,N>(陣列容器),儲存N個T型別的元素,長度初始化後不可變
vector
deque
list
forward_list
array,vector,deque常見函式
1.STL array
聲明後長度不可變
array<typename T,size_t N>
array<double,10> arr{};//不指定值,預設為0
array<double, 10> values {0.5,1.0,1.5,,2.0};//剩餘元素為0
成員函式 | 功能 |
---|---|
begin() | 返回指向容器中第一個元素的隨機訪問迭代器。 |
end() | 返回指向容器最後一個元素之後一個位置的隨機訪問迭代器,通常和 begin() 結合使用。 |
rbegin() | 返回指向最後一個元素的隨機訪問迭代器。 |
rend() | 返回指向第一個元素之前一個位置的隨機訪問迭代器。 |
cbegin() | 和 begin() 功能相同,只不過在其基礎上增加了 const 屬性,不能用於修改元素。 |
cend() | 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
crbegin() | 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
crend() | 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
size() | 返回容器中當前元素的數量,其值始終等於初始化 array 類的第二個模板引數 N。 |
max_size() | 返回容器可容納元素的最大數量,其值始終等於初始化 array 類的第二個模板引數 N。 |
empty() | 判斷容器是否為空,和通過 size()==0 的判斷條件功能相同,但其效率可能更快。 |
at(n) | 返回容器中 n 位置處元素的引用,該函式自動檢查 n 是否在有效的範圍內,如果不是則丟擲 out_of_range 異常。 |
front() | 返回容器中第一個元素的直接引用,該函式不適用於空的 array 容器。 |
back() | 返回容器中最後一個元素的直接應用,該函式同樣不適用於空的 array 容器。 |
data() | 返回一個指向容器首個元素的指標。利用該指標,可實現複製容器中所有元素等類似功能。 |
fill(val) | 將 val 這個值賦值給容器中的每個元素。 |
array1.swap(array2) | 交換 array1 和 array2 容器中的所有元素,但前提是它們具有相同的長度和型別。 |
array通過[]訪問元素,為了避免越界,可以使用at()成員函式,越界會丟擲out_of_range異常
2.STL vector
vector<double> val;
//擴容,當val.size()>20則不做操作
val.reserve(20);
std::vector<int> primes {2, 3, 5, 7, 11, 13, 17, 19};
std::vector<double> values(20);//指定元素個數,初始為0
std::vector<double> values(20,1);//指定元素個數,初始為1
函式成員 | 函式功能 |
---|---|
begin() | 返回指向容器中第一個元素的迭代器。 |
end() | 返回指向容器最後一個元素所在位置後一個位置的迭代器,通常和 begin() 結合使用。 |
rbegin() | 返回指向最後一個元素的迭代器。 |
rend() | 返回指向第一個元素所在位置前一個位置的迭代器。 |
cbegin() | 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
cend() | 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
crbegin() | 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
crend() | 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
size() | 返回實際元素個數。 |
max_size() | 返回元素個數的最大值。這通常是一個很大的值,一般是 232-1,所以我們很少會用到這個函式。 |
resize() | 改變實際元素的個數。 |
capacity() | 返回當前容量。 |
empty() | 判斷容器中是否有元素,若無元素,則返回 true;反之,返回 false。 |
reserve() | 增加容器的容量。 |
shrink _to_fit() | 將記憶體減少到等於當前元素實際所使用的大小。 |
operator[ ] | 過載了 [ ] 運算子,可以向訪問陣列中元素那樣,通過下標即可訪問甚至修改 vector 容器中的元素。 |
at() | 使用經過邊界檢查的索引訪問元素。 |
front() | 返回第一個元素的引用。 |
back() | 返回最後一個元素的引用。 |
data() | 返回指向容器中第一個元素的指標。 |
assign() | 用新元素替換原有內容。 |
push_back() | 在序列的尾部新增一個元素。 |
pop_back() | 移出序列尾部的元素。 |
insert() | 在指定的位置插入一個或多個元素。並返回新插入元素所在位置的迭代器 |
erase() | 移出一個元素或一段元素。,根據索引刪除, |
clear() | 移出所有的元素,容器大小變為 0。 |
swap() | 交換兩個容器的所有元素。 |
remove() | 根據值刪除元素,不會改變容器的大小和容量 |
emplace() | 在指定的位置直接生成一個元素。 |
emplace_back() | 在序列尾部生成一個元素。 |
訪問元素的方式
vec[n];
vec.at(n);
vec.front();//首元素
vec.back();//尾元素
vec.data();//返回首元素的指標
*(vec.data()+n);
push_back();
emplace_back();
這兩個函式都可以在容器末尾新增元素
push_back新增元素時,會生成一個元素,再將元素移動(或拷貝)至容器中,而emplace_back會
直接在容器末尾生成,因此emplace_back更加高效
iterator insert(pos,elem);//在指定位置之前插入一個元素elem
iterator insert(pos,n,elem);//在指定位置之前插入n個元素elem
iterator insert(pos,first,last);//在pos之前,插入其他容器中[first,last)區域內的所有元素,返回第一個新元素的迭代器的位置
iterator insert(pos,initlist);//在pos之前插入初始化列表的所有元素,返回第一個新元素的迭代器的位置
iterator emplace(const_iterator pos,args);
pos:指定插入元素的位置,args:新插入元素的建構函式對應的多個引數
刪除元素
erase(n);//刪除指定位置的元素
erase(first,last);//刪除指定位置[first,last)的元素
remove(pos,n);//從pos開始刪除值為n的元素
remove不會改變容器大小和容量
remove() 的實現原理是,在遍歷容器中的元素時,一旦遇到目標元素,就做上標記,然後繼續遍歷,直到找到一個非目標元素,即用此元素將最先做標記的位置覆蓋掉,同時將此非目標元素所在的位置也做上標記,等待找到新的非目標元素將其覆蓋。因此,1,3,3,4,3,5,remove(3)如果將上面程式中 demo 容器的元素全部輸出,得到的結果為 1 4 5 4 3 5
。
因此刪除指定元素需要和erase搭配
auto it=remove(demo.begin(),demo.end(),3);
demo.erase(it,demo.end());
vector<int> demo{1,2,3};
demo.clear();
//demo.size()=0
//demo.capacity()=6
vector<bool>並不是一個STL容器,也不容納bool
vector<bool> 打包 bool 以節省空間,每個儲存在“vector”中的“bool”佔用一個單獨的bit,而禁止有指向單個位元的指標。
3.STL deque
deque相比vector,可以高效的在容器底部或尾部插入元素,且容器內的元素不一定會放在一段連續記憶體裡
deque<int> dq;//初始化空佇列
deque<int> dq(100);//初始化100個預設值的佇列
deque<int> dq(100,1);//初始化100個1的佇列
函式成員 | 函式功能 |
---|---|
begin() | 返回指向容器中第一個元素的迭代器。 |
end() | 返回指向容器最後一個元素所在位置後一個位置的迭代器,通常和 begin() 結合使用。 |
rbegin() | 返回指向最後一個元素的迭代器。 |
rend() | 返回指向第一個元素所在位置前一個位置的迭代器。 |
cbegin() | 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
cend() | 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
crbegin() | 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
crend() | 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
size() | 返回實際元素個數。 |
max_size() | 返回容器所能容納元素個數的最大值。這通常是一個很大的值,一般是 232-1,我們很少會用到這個函式。 |
resize() | 改變實際元素的個數。 |
empty() | 判斷容器中是否有元素,若無元素,則返回 true;反之,返回 false。 |
shrink _to_fit() | 將記憶體減少到等於當前元素實際所使用的大小。 |
at() | 使用經過邊界檢查的索引訪問元素。 |
front() | 返回第一個元素的引用。 |
back() | 返回最後一個元素的引用。 |
assign() | 用新元素替換原有內容。 |
push_back() | 在序列的尾部新增一個元素。 |
push_front() | 在序列的頭部新增一個元素。 |
pop_back() | 移除容器尾部的元素。 |
pop_front() | 移除容器頭部的元素。 |
insert() | 在指定的位置插入一個或多個元素。 |
erase() | 移除一個元素或一段元素。 |
clear() | 移出所有的元素,容器大小變為 0。 |
swap() | 交換兩個容器的所有元素。 |
emplace() | 在指定的位置直接生成一個元素。 |
emplace_front() | 在容器頭部生成一個元素。和 push_front() 的區別是,該函式直接在容器頭部構造元素,省去了複製移動元素的過程。 |
emplace_back() | 在容器尾部生成一個元素。和 push_back() 的區別是,該函式直接在容器尾部構造元素,省去了複製移動元素的過程。 |
注:建立first容器後,容器進行新增操作,會導致first失效
訪問deque元素
dq[n];//訪問容器的中第n個元素
dq.at(n);//訪問容器的中第n個元素,有邊界控制
dq.front();//訪問dq的首元素
dq.back();//訪問dq的尾元素
4.STL list
list雙向連結串列容器,各元素靠指標維持順序,分別指向前後兩個元素,不能通過索引訪問元素
list<int> l;
list<int> l(10);
list<int> l(10,5);
函式 | 功能 |
---|---|
remove(val) | 刪除容器中所有等於 val 的元素。 |
remove_if() | 刪除容器中滿足條件的元素。 |
unique() | 刪除容器中相鄰的重複元素,只保留一個。 |
merge() | 合併兩個事先已排好序的 list 容器,並且合併之後的 list 容器依然是有序的。 |
sort() | 通過更改容器中元素的位置,將它們進行排序。 |
reverse() | 反轉容器中元素的順序。 |
訪問元素:
l.front();//返回list的第一個元素的引用
l.back();//返回list的最後一個元素的引用
list插入元素:
push_front();
push_back();
emplace_back();
emplace_front();
emplace();//在指定位置生成元素
insert();//在指定位置插入元素
splice();//在指定位置插入其他list容器中的元素
splice 將其他list容器中的元素添加當前list容器中指定位置處。
void splice(iterator pos,list& x);//pos:插入位置,x:另一個list容器
void splice(iterator pos,list& x,iterator i);//將x容器中i指向的元素移動到當前容器中pos指明的位置
void splice(iterator pos,list& x,iterator first,iterator last);//將x容器[first,last)範圍內所有元素移動到當前容器pos位置上。
splice方法會將x容器中的相應元素新增到當前容器,該元素會從x中刪除
unique()
void unique();
void unique(BinaryPredicate);//傳入二元謂詞函式
兩種方式都可去重,第二種可以自定義去重規則
remove_if();//傳入自定義為此函式,刪除滿足條件的元素
5.STL forward_list
C++11新容器,底層為單鏈表結構,資料儲存是分散隨機的。可以在序列任何位置新增和刪除元素。
forward_list只提供前向迭代器,無rbegin,rend等函式
相較於list,消耗記憶體小,空間效率高
forward_list<int> fl;
forward_list<int> fl(10);
forward_list<int> fl(10,5);//初始化10個5
before_begin() | 返回一個前向迭代器,其指向容器中第一個元素之前的位置。 |
---|---|
begin() | 返回一個前向迭代器,其指向容器中第一個元素的位置。 |
end() | 返回一個前向迭代器,其指向容器中最後一個元素之後的位置。 |
cbefore_begin() | 和 before_begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
cbegin() | 和 begin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
cend() | 和 end() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改元素。 |
empty() | 判斷容器中是否有元素,若無元素,則返回 true;反之,返回 false。 |
max_size() | 返回容器所能包含元素個數的最大值。這通常是一個很大的值,一般是 232-1,所以我們很少會用到這個函式。 |
front() | 返回第一個元素的引用。 |
assign() | 用新元素替換容器中原有內容。 |
push_front() | 在容器頭部插入一個元素。 |
emplace_front() | 在容器頭部生成一個元素。該函式和 push_front() 的功能相同,但效率更高。 |
pop_front() | 刪除容器頭部的一個元素。 |
emplace_after() | 在指定位置之後插入一個新元素,並返回一個指向新元素的迭代器。和 insert_after() 的功能相同,但效率更高。 |
insert_after() | 在指定位置之後插入一個新元素,並返回一個指向新元素的迭代器。 |
erase_after() | 刪除容器中某個指定位置或區域內的所有元素。 |
swap() | 交換兩個容器中的元素,必須保證這兩個容器中儲存的元素型別是相同的。 |
resize() | 調整容器的大小。 |
clear() | 刪除容器儲存的所有元素。 |
splice_after() | 將某個 forward_list 容器中指定位置或區域內的元素插入到另一個容器的指定位置之後。 |
remove(val) | 刪除容器中所有等於 val 的元素。 |
remove_if() | 刪除容器中滿足條件的元素。 |
unique() | 刪除容器中相鄰的重複元素,只保留一個。 |
merge() | 合併兩個事先已排好序的 forward_list 容器,並且合併之後的 forward_list 容器依然是有序的。 |
sort() | 通過更改容器中元素的位置,將它們進行排序。 |
reverse() | 反轉容器中元素的順序。 |
forward_list不提供size函式,如果想獲取長度,採用iterator中的distance函式。
int count=distance(begin(fl),end(fl));
int count=distance(fl.begin(),fl.end());
begin(),end()為STL容器方法,可以獲取容器第一個,最後一個元素的迭代器
begin(),end(),引數可以是普通陣列,可可以是容器,為普通陣列將返回第一個、最後一個元素的指標,為容器返回迭代器。
6.vector自定義排序
-
過載運算子
struct Book{ int page; string name; bool operator <(const Book& b) const // 升序排序時必須寫的函式 { return page < b.page; } bool operator >(const Book& b) const // 降序排序時必須寫的函式 { return page > b.page; } } vector<Book> books; sort(books.begin(), books.end(), less<Book>());
-
全域性比較函式
struct Book{ int page; string name; }; bool lessmark(const Book& b1, const Book& b2) { return b1.page < b2.page; } bool greatermark(const Book& b1, const Book& b2) { return b1.page > b2.page; } vector<Book> books; sort(books.begin(), books.end(), lessmark); //升序排序
-
仿生函式(重寫())
struct Book{ int page; string name; }; class CompLess{ public: bool operator ()(const Book& b1, const Book& b2) { return b1.page < b2.page; } }; class CompGreater{ public: bool operator ()(const Book& b1, const Book& b2) { return b1.page > b2.page; } }; vector<Book> books; sort(books.begin(), books.end(), CompLess()); //升序排序