STL程序員
STL(Standard Template Library,標準模板庫),它是由惠普實驗室開發的一系列標準化的組件,目前是C++的一部分。算法
‚STL的代碼從廣義上講分爲三類:container(容器)、iterator(迭代器)和algorithm(算法),容器和算法經過迭代器能夠進行無縫地鏈接。windows
ƒstring,wstring也是STL的一部分數組
使用STL的好處數據結構
STL是C++的一部分,所以不用額外安裝什麼,它被內建在你的編譯器以內。app
STL的一個重要特色是數據結構和算法的分離。儘管這是個簡單的概念,可是這種分離確實使得STL變得很是通用。例如,STL的sort()函數能夠用來操做vector,list等容器。less
STL具備高可重用性,高性能,高移植性,跨平臺的優勢:dom
高可重用性:STL中幾乎全部的代碼都採用了模板類和模版函數的方式實現,這相比於傳統的由函數和類組成的庫來講提供了更好的代碼重用機會。關於模板的介紹,在第二講會講解。 高性能:如map能夠高效地從十萬條記錄裏面查找出指定的記錄,由於map是採用紅黑樹的變體實現的。(紅黑樹是平橫二叉樹的一種)
高移植性:如在項目A上用STL編寫的模塊,能夠直接移植到項目B上。數據結構和算法
跨平臺:如用windows的Visual Studio編寫的代碼能夠在Mac OS的XCode上直接編譯。ide
程序員能夠不用思考STL具體的實現過程,只要可以熟練使用STL就OK了。這樣他們就能夠把精力放在程序開發的別的方面。
string講解綱要
string是什麼
string是STL的字符串類型,一般用來表示字符串。而在使用string以前,字符串一般是用char*表示的。
string與char*的比較
string不用考慮內存釋放和越界。
string管理char*所分配的內存。每一次string的複製,取值都由string類負責維護,不用擔憂複製越界和取值越界等。
string支持運算。(這個等下會詳細作記錄)
如: string a; string b; a += b;
‚string提供了一系列的字符串操做函數(這個等下會詳作記錄)
查找find, 拷貝copy,刪除erase 替換replace,插入insert,等等
string使用以前的準備
#include
using namespace std;
string的構造函數
默認構造函數:
string(); //構造一個空的字符串string s1。
拷貝構造函數:
string(const string &str);//構造一個與str同樣的string。如string s1(s2)。
帶參數的構造函數
string(const char *s); //用字符串s初始化
string(int n,char c); //用n個字符c初始化
string的存取字符操做
string類的字符操做:
const char &operator[] (int n) const;
const char &at(int n) const;
char &operator[] (int n);
char &at(int n);
char c = strA[3];
char d = strA.at(5);
以上兩句對應前兩個方法
strA[3] = ‘X’;
strA.at(5) = ‘Y’;
以上兩句對應後兩個方法
operator[]和at()均返回當前字符串中第n個字符,但兩者是有區別的。
主要區別在於at()在越界時會拋出異常,[]在恰好越界時會返回(char)0,再繼續越界時,編譯器直接出錯。 若是你的程序但願能夠經過try,catch捕獲異常,建議採用at()。
從string取得const char*的操做
string類的字符操做:
const char *c_str() const; //返回一個以’\0’結尾的字符串
把string拷貝到char*指向的空間的操做
int copy(char *s, int n, int pos=0) const;
把當前串中以pos開始的n個字符拷貝到以s爲起始位置的字符數組中,返回實際拷貝的數目。注意要保證s所指向的空間足夠大以容納當前字符串,否則會越界。
string的長度
int length() const; //返回當前字符串的長度。長度不包括字符串結尾的’\0’。
bool empty() const; //當前字符串是否爲空
string的賦值
string &operator=(const string &s);//把字符串s賦給當前的字符串
string &assign(const char *s); //把字符串s賦給當前的字符串
string &assign(const char *s, int n); //把字符串s的前n個字符賦給當前的字符串
string &assign(const string &s); //把字符串s賦給當前字符串
string &assign(int n,char c); //用n個字符c賦給當前字符串
string &assign(const string &s,int start, int n); //把字符串s中從start開始的n個字符賦給當前字符串
string的鏈接
string &operator+=(const string &s); //把字符串s鏈接到當前字符串結尾
string &operator+=(const char *s);//把字符串s鏈接到當前字符串結尾
string &append(const char *s); //把字符串s鏈接到當前字符串結尾
string &append(const char *s,int n); //把字符串s的前n個字符鏈接到當前字符串結尾
string &append(const string &s); //同operator+=()
string &append(const string &s,int pos, int n);//把字符串s中從pos開始的n個字符鏈接到當前字符串結尾
string &append(int n, char c); //在當前字符串結尾添加n個字符c
string的比較
int compare(const string &s) const; //與字符串s比較
int compare(const char *s) const; //與字符串s比較
compare函數在>時返回 1,<時返回 -1,==時返回 0。比較區分大小寫,比較時參考字典順序,排越前面的越小。大寫的A比小寫的a小。
string的子串
string substr(int pos=0, int n=npos) const; //返回由pos開始的n個字符組成的子字符串
string的查找
int find(char c,int pos=0) const; //從pos開始查找字符c在當前字符串的位置
int find(const char *s, int pos=0) const; //從pos開始查找字符串s在當前字符串的位置
int find(const string &s, int pos=0) const; //從pos開始查找字符串s在當前字符串中的位置
find函數若是查找不到,就返回-1
int rfind(char c, int pos=npos) const; //從pos開始從後向前查找字符c在當前字符串中的位置
int rfind(const char *s, int pos=npos) const;
int rfind(const string &s, int pos=npos) const;
//rfind是反向查找的意思,若是查找不到, 返回-1
string的插入
string &insert(int pos, const char *s);
string &insert(int pos, const string &s);
//前兩個函數在pos位置插入字符串s
string &insert(int pos, int n, char c); //在pos位置 插入n個字符c
string的刪除
string &erase(int pos=0, int n=npos); //刪除pos開始的n個字符,返回修改後的字符串
string的替換
string &replace(int pos, int n, const char *s);//刪除從pos開始的n個字符,而後在pos處插入串s
string &replace(int pos, int n, const string &s); //刪除從pos開始的n個字符,而後在pos處插入串s
void swap(string &s2); //交換當前字符串與s2的值
string與wstring的區別
string是對char*的管理,一個字符只佔一個字節大小。一個漢字佔兩個字節,ASCII編碼。
wstring是對wchar_t*的管理,一個字符佔兩個字節大小,一個漢字佔兩個字節,Unicode編碼。
wstring的使用方法跟string相似,區別主要在於函數參數char與函數參數wchar_t
string與wstring的轉換
第一種方法:調用Windows的API函數:WideCharToMultiByte()函數和MultiByteToWideChar()函數。
第二種方法
使用ATL的CA2W類與CW2A類。或使用A2W宏與W2A宏。
第三種方法,跨平臺的方法,使用CRT庫的mbstowcs()函數和wcstombs()函數,需設定locale。
如下是第三種方法的實現例子。
#include
#include <locale.h>
using namespace std;
//wstring轉成string
string ws2s(const wstring &ws)
{
string curLocale = setlocale(LC_ALL,NULL); //curLocale=「C」;
setlocale(LC_ALL,「chs」);
const wchar_t * _Source=ws.c_str();
size_t _Dsize=2*ws.size()+1;
char * _Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
string result = _Dest;
delete[] _Dest;
setlocale(LC_ALL,curLocale.c_str());
return result;
}
//string轉成wstring
wstring s2ws(const string &s)
{
string curLocale = setlocale(LC_ALL,NULL); //curLocale = 「C」
setlocale(LC_ALL, 「chs」);
const char *_Source = s.c_str();
size_t _Dsize = s.size()+1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest,0,_Dsize);
mbstowcs(_Dest,_Source,_Dsize);
wstring result = _Dest;
delete[] _Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
編碼統一化,編寫單一源代碼
若是咱們想創建兩個版本的程序,一個處理ASCII字符串,另外一個處理Unicode字符串,最好的解決辦法是編寫出既能按ASCII編譯又能按Unicode編譯的單一源代碼。把如下代碼加入到程序中,只要修改一個宏就能知足咱們的要求。
#ifdef _UNICODE
typedef wstring tstring;
typedef wchar_t tchar;
#define _T(x) L ## x
#else
typedef string tstring;
typedef char tchar;
#define _T(x) x
#endif
回顧
這一講,主要講解以下要點:
1、什麼是STL,使用STL的好處
STL的代碼從廣義上講分爲三類:container(容器)、iterator(迭代器)和algorithm(算法),容器和算法經過迭代器能夠進行無縫鏈接。
string,wstring也是STL的一部分。
STL具備高可重用性,高性能,高移植性,跨平臺的優勢。
2、STL的string類型的使用方法
string是什麼,string與char*的比較,string使用以前的準備,string的構造函數,取字符操做,取const char*的操做,拷貝,長度,賦值,鏈接,比較,子串,查找,插入,刪除,替換,與wstring的區別與轉換,編碼統一化。
講解要點
這一講,主要講解以下要點:
1、模板的簡介,函數模板與類模板的用法;
2、容器的簡介,容器的分類,各個容器的數據結構;
3、容器vector的具體用法(包括迭代器的具體用法)
模板的簡介
模板是實現代碼重用機制的一種工具,實質就是實現類型參數化,即把類型定義爲參數。
C++提供兩種模板:函數模板,類模板。
函數模板就是創建一個通用的函數,其函數返回類型和形參類型不具體指定,而是用虛擬的類型來表明。
凡是函數體相同的函數均可以用函數模板來代替,沒必要定義多個函數,只需在模板中定義一次便可。
在調用函數時系統會根據實參的類型來取代模板中的虛擬類型,從而實現了不一樣函數的功能。
類模板的簡介
和函數模板同樣,類模板就是創建一個通用類,其數據成員的類型、成員函數的返回類型和參數類形均可以不具體指定,而用虛擬的類型來表明。
當使用類模板創建對象時,系統會根據實參的類型取代類模板中的虛擬類型,從而實現不一樣類的功能。
能夠定義多種類型的形參。
template<typename T1, typename T2>
class CTest
{…};
對象實例化時:
CTest testA<int, float>;
CTest testB<double, string>
容器的簡介
容器是用來存放、管理一組元素的數據集合。
容器的數據結構示意圖:
容器的分類
容器有序列式容器(Sequence containers)和關聯式容器(Associated containers)
序列式容器:每一個元素的位置取決於元素被插入的時機,被插入時設置的位置,和元素值自己無關。
序列式容器有vector、deque、list,queue, stack
關聯式容器:元素位置取決於特定的排序準則,和插入順序無關。
關聯式容器有set、multiset、map、multimap
vector與迭代器的講解綱要
vector的簡介
vector是將元素置於一個動態數組中加以管理的容器。
vector能夠隨機存取元素(支持索引值直接存取, 用[]操做符或at()方法,這個等下會詳講)。
vector尾部添加或移除元素很是快速。可是在中部或頭部插入元素或移除元素比較費時
vector使用以前的準備
#include
using namespace std;
vector對象的默認構造
vector採用模板類實現,vector對象的默認構造形式:vector vecT; 如:
vector vecInt; //一個存放int的vector容器。
vector vecFloat; //一個存放float的vector容器。
vector vecString; //一個存放string的vector容器。
… //尖括號內還能夠設置指針類型或自定義類型。
Class CA{};
vector<CA*> vecpCA; //用於存放CA對象的指針的vector容器。
vector vecCA; //用於存放CA對象的vector容器。因爲容器元素的存放是按值複製的方式進行的,因此此時CA必須提供CA的拷貝構造函數,以保證CA對象間拷貝正常。
vector末尾的添加移除操做
vector.push_back(elem); //在容器尾部加入一個元素。
vector.pop_back(); //移除容器中最後一個元素
例如: vector vecInt;
vecInt.push_back(1); vecInt.push_back(3); vecInt.push_back(5);vecInt.push_back(7); vecInt.push_back(9);
此時容器vecInt就包含了按順序的1,3,5,7,9元素。
若是在此基礎上再運行語句vecInt.pop_back();
vecInt.pop_back();此時容器vecInt就包含了按順序的1,3,5元素。
vector的數據存取
vec.at(idx); //返回索引idx所指的數據,若是idx越界,拋出out_of_range異常。
vec[idx]; //返回索引idx所指的數據,越界時,運行直接報錯。
例如:假設vecInt是用vector 聲明的,且已包含按順序的1,3,5,7,9值;此時vecInt.at(2)==vecInt[2]==5。若運行代碼vecInt.at(2)=8,或者運行vecInt[2]=8,則vecInt就包含按順序的1,3,8,7,9值。
vector.front(); //返回第一個數據。
vector.back(); //返回最後一個數據。
vector vecInt; //假設包含{1,3,5,7,9}
int iF = vector.front(); //iF==1
int iB = vector.back(); //iB==9
vector.front() = 11; //vecInt包含{11,3,5,7,9}
vector.back() = 19; //vecInt包含{11,3,5,7,19}
迭代器的簡介
迭代器是一個「可遍歷STL容器內所有或部分元素」的對象。
迭代器指出容器中的一個特定位置。
迭代器就如同一個指針。
迭代器提供對一個容器中的對象的訪問方法,而且能夠定義了容器中對象的範圍。
這裏大概介紹一下迭代器的類別。
輸入迭代器:也有叫法稱之爲「只讀迭代器」,它從容器中讀取元素,只能一次讀入一個元素向前移動,只支持一遍算法,同一個輸入迭代器不能兩遍遍歷一個序列。
輸出迭代器:也有叫法稱之爲「只寫迭代器」,它往容器中寫入元素,只能一次寫入一個元素向前移動,只支持一遍算法,同一個輸出迭代器不能兩遍遍歷一個序列。
正向迭代器:組合輸入迭代器和輸出迭代器的功能,還能夠屢次解析一個迭代器指定的位置,能夠對一個值進行屢次讀/寫。
雙向迭代器:組合正向迭代器的功能,還能夠經過–操做符向後移動位置。
隨機訪問迭代器:組合雙向迭代器的功能,還能夠向前向後跳過任意個位置,能夠直接訪問容器中任何位置的元素。
目前本系列教程所用到的容器,都支持雙向迭代器或隨機訪問迭代器,下面將會詳細介紹這兩個類別的迭代器。
雙向迭代器與隨機訪問迭代器
雙向迭代器支持的操做:
it++, ++it, it–, --it,*it, itA = itB,
itA == itB,itA != itB
其中list,set,multiset,map,multimap支持雙向迭代器。
隨機訪問迭代器支持的操做:
在雙向迭代器的操做基礎上添加
it+=i, it-=i, it+i(或it=it+i),it[i],
itA<itB, itA<=itB, itA>itB, itA>=itB 的功能。
其中vector,deque支持隨機訪問迭代器。
vector與迭代器的配合使用
vec.begin(); //返回容器中第一個元素的迭代器。
vec.end(); //返回容器中最後一個元素以後的迭代器。
例如:vecInt是用vector聲明的容器,假設已經包含了按順序的1,3,5,7,9元素。
vector::iterator it; //聲明容器vector的迭代器。
運行 it=vecInt.begin(); //此時*it==1。
運行++it; // 或者it++; 此時*it==3,前++的效率比後++的效率高,前++返回引用,後++返回值。
運行it += 2; //此時*it==7。
運行it = it +1; //此時*it=9。
運行++it; //此時it==vecInt.end(); 此時不能再執行*it;
如下是用迭代器遍歷容器的例子。
假設vecInt是用vector聲明的容器,裏面包含按順序的1,3,5,7,9元素。
for(vector::iterator it=vecInt.begin(); it!=vecInt.end(); ++it)
{
int iItem = *it; cout << iItem; //或直接使用 cout << *it;
}
這樣子便打印出1 3 5 7 9
vec.rbegin(); //返回容器中倒數第一個元素的迭代器。
vec.rend(); //返回容器中倒數最後一個元素以後的迭代器。
例如: vecInt是vector聲明的容器,已包含按順序的1,3,5,7,9元素。現要求逆序打印這些元素。
迭代器還有其它兩種聲明方法:
如:
vector::const_iterator
vector::const_reverse_iterator
這兩種分別是
vector::iterator
vector::reverse_iterator
的只讀形式,使用這兩種迭代器時,不會修改到容器中的值。
備註:不過容器中的insert和erase方法僅接受這四種類型中的iterator,其它三種不支持。《Effective STL》建議咱們儘可能使用iterator取代const_iterator、reverse_iterator和const_reverse_iterator。
vector對象的帶參數構造
vector(beg,end); //構造函數將[beg, end)區間中的元素拷貝給自己。注意該區間是左閉右開的區間。
vector(n,elem); //構造函數將n個elem拷貝給自己。
vector(const vector &vec); //拷貝構造函數。
vector的賦值
vector.assign(beg,end); //將[beg, end)區間中的數據拷貝賦值給自己。注意該區間是左閉右開的區間。
vector.assign(n,elem); //將n個elem拷貝賦值給自己。
vector& operator=(const vector &vec); //重載等號操做符
vector.swap(vec); // 將vec與自己的元素互換。
vector的大小
vector.size(); //返回容器中元素的個數
vector.empty(); //判斷容器是否爲空
vector.resize(num); //從新指定容器的長度爲num,若容器變長,則以默認值填充新位置。若是容器變短,則末尾超出容器長度的元素被刪除。
vector.resize(num, elem); //從新指定容器的長度爲num,若容器變長,則以elem值填充新位置。若是容器變短,則末尾超出容器長度的元素被刪除。
例如 vecInt是vector 聲明的容器,現已包含1,2,3元素。
執行vecInt.resize(5); //此時裏面包含1,2,3,0,0元素。
再執行vecInt.resize(8,3); //此時裏面包含1,2,3,0,0,3,3,3元素。
再執行vecInt.resize(2); //此時裏面包含1,2元素。
vector的插入
vector.insert(pos,elem); //在迭代器pos位置插入一個elem元素的拷貝,返回新數據的位置。
vector.insert(pos,n,elem); //在pos位置插入n個elem數據,無返回值。
vector.insert(pos,beg,end); //在pos位置插入[beg,end)區間的數據,無返回值。
vector的刪除
vector.clear(); //移除容器的全部數據
vec.erase(beg,end); //刪除[beg,end)區間的數據,返回下一個數據的位置。
vec.erase(pos); //刪除pos位置的數據,返回下一個數據的位置。
例如: vecInt是用vector聲明的容器,現已包含按順序的1,3,5,6,9元素。
vector::iterator itBegin=vecInt.begin()+1;
vector::iterator itEnd=vecInt.begin()+3;
vecInt.erase(itBegin,itEnd);
//此時容器vecInt包含按順序的1,6,9三個元素。
例如 vecInt是用vector聲明的容器,現已包含按順序的1,3,2,3,3,3,4,3,5,3元素。現要求刪除容器中全部等於3的元素。
for(vector::iterator it=vecInt.being(); it!=vecInt.end(); ) //小括號裏不需寫 ++it
{
if(*it == 3){ it = vecInt.erase(it); //以迭代器爲參數,刪除元素3,並把數據刪除後的下一個元素位置返回給迭代器。 //此時,不執行 ++it; } else { ++it; } }
回顧
這一講,主要講解以下要點:
1、模板的簡介,函數模板與類模板的用法
類型參數化
2、容器的簡介,容器的分類,各個容器的數據結構
vector,deque,list,set,multiset,map,multimap
3、容器vector的具體用法(包括迭代器的具體用法)。
vertor簡介,vector使用以前的準備,vector對象的默認構造,vector末尾的添加移除操做,vector的數據存取,迭代器的簡介,雙向迭代器與隨機訪問迭代器
vector與迭代器的配合使用,vector對象的帶參數構造,vector的賦值,vector的大小,vector的插入,vector的刪除。
這一講,主要講解以下要點:
1、容器deque的使用方法;
2、容器queue,stack的使用方法;
3、容器list的使用方法。
deque的講解綱要
deque的簡介
deque是「double-ended queue」的縮寫,和vector同樣都是STL的容器,deque是雙端的,而vector是單端的。
deque在接口上和vector很是類似,在許多操做的地方能夠直接替換。
deque能夠隨機存取元素(支持索引值直接存取, 用[]操做符或at()方法,這個等下會詳講)。
deque頭部和尾部添加或移除元素都很是快速。可是在中部安插元素或移除元素比較費時。
deque使用以前的準備
#include
using namespace std;
deque對象的默認構造
deque採用模板類實現,deque對象的默認構造形式:deque deqT; 如:
deque deqInt; //一個存放int的deque容器。
deque deq Float; //一個存放float的deque容器。
deque deq String; //一個存放string的deque容器。
…
//尖括號內還能夠設置指針類型或自定義類型。
deque末尾的添加移除操做
deque.push_back(elem); //在容器尾部添加一個數據
deque.push_front(elem); //在容器頭部插入一個數據
deque.pop_back(); //刪除容器最後一個數據
deque.pop_front(); //刪除容器第一個數據
deque的數據存取
deque.at(idx); //返回索引idx所指的數據,若是idx越界,拋出out_of_range。
deque[idx]; //返回索引idx所指的數據,若是idx越界,不拋出異常,直接出錯。
deque.front(); //返回第一個數據。
deque.back(); //返回最後一個數據。
deque與迭代器
deque.begin(); //返回容器中第一個元素的迭代器。
deque.end(); //返回容器中最後一個元素以後的迭代器。
deque.rbegin(); //返回容器中倒數第一個元素的迭代器。
deque.rend(); //返回容器中倒數最後一個元素以後的迭代器。
deque對象的帶參數構造
deque(beg,end); //構造函數將[beg, end)區間中的元素拷貝給自己。注意該區間是左閉右開的區間。
deque(n,elem); //構造函數將n個elem拷貝給自己。
deque(const deque &deq); //拷貝構造函數。
deque的賦值
deque.assign(beg,end); //將[beg, end)區間中的數據拷貝賦值給自己。注意該區間是左閉右開的區間。
deque.assign(n,elem); //將n個elem拷貝賦值給自己。
deque& operator=(const deque &deq); //重載等號操做符
deque.swap(deq); // 將vec與自己的元素互換。
deque的大小
deque.size(); //返回容器中元素的個數
deque.empty(); //判斷容器是否爲空
deque.resize(num); //從新指定容器的長度爲num,若容器變長,則以默認值填充新位置。若是容器變短,則末尾超出容器長度的元素被刪除。
deque.resize(num, elem); //從新指定容器的長度爲num,若容器變長,則以elem值填充新位置。若是容器變短,則末尾超出容器長度的元素被刪除。
例如 deqInt是deque 聲明的容器,現已包含1,2,3元素。
執行deqInt.resize(5); //此時裏面包含1,2,3,0,0元素。
再執行deqInt.resize(8,3); //此時裏面包含1,2,3,0,0,3,3,3元素。
再執行deqInt.resize(2); //此時裏面包含1,2元素。
deque的插入
deque.insert(pos,elem); //在pos位置插入一個elem元素的拷貝,返回新數據的位置。
deque.insert(pos,n,elem); //在pos位置插入n個elem數據,無返回值。
deque.insert(pos,beg,end); //在pos位置插入[beg,end)區間的數據,無返回值。
deque的刪除
deque.clear(); //移除容器的全部數據
deque.erase(beg,end); //刪除[beg,end)區間的數據,返回下一個數據的位置。
deque.erase(pos); //刪除pos位置的數據,返回下一個數據的位置。
queue,stack的講解綱要
queue的簡介
queue是隊列容器,是一種「先進先出」的容器。
queue是簡單地裝飾deque容器而成爲另外的一種容器。
queue使用以前的準備
#include
using namespace std;
queue對象的默認構造
queue採用模板類實現,queue對象的默認構造形式:queue queT; 如:
queue queInt; //一個存放int的queue容器。
queue queFloat; //一個存放float的queue容器。
queue queString; //一個存放string的queue容器。
//尖括號內還能夠設置指針類型或自定義類型。
queue的push與pop操做
queue.push(elem); //往隊尾添加元素
queue.pop(); //從隊頭移除第一個元素
例如:queue queInt;
queInt.push(1);queInt.push(3);…
queInt.push(5);queInt.push(7);
queInt.push(9);queInt.pop();
queInt.pop();
此時queInt存放的元素是5,7,9
queue對象的拷貝構造與賦值
queue(const queue &que); //拷貝構造函數
queue& operator=(const queue &que); //重載等號操做符
如:
queue queIntA, queIntC;…
queue queIntB(queIntA);
queue queIntD;
queIntD = queIntC;
queue的數據存取
queue.back(); //返回最後一個元素
queue.front(); //返回第一個元素
queue的大小
queue.empty(); //判斷隊列是否爲空
queue.size(); //返回隊列的大小
stack的簡介
stack是堆棧容器,是一種「先進後出」的容器。
stack是簡單地裝飾deque容器而成爲另外的一種容器。
stack使用以前的準備
#include
using namespace std;
stack對象的默認構造
stack採用模板類實現, stack對象的默認構造形式: stack stkT; 如:
stack stkInt; //一個存放int的stack容器。
stack stkFloat; //一個存放float的stack容器。
stack stkString; //一個存放string的stack容器。
//尖括號內還能夠設置指針類型或自定義類型。
stack的push與pop操做
stack.push(elem); //往棧頭添加元素
stack.pop(); //從棧頭移除第一個元素
例如:stack stkInt;
stkInt.push(1);stkInt.push(3);stkInt.pop();
stkInt.push(5);stkInt.push(7);
stkInt.push(9);stkInt.pop();
stkInt.pop();
此時stkInt存放的元素是1,5
stack對象的拷貝構造與賦值
stack(const stack &stk); //拷貝構造函數
stack& operator=(const stack &stk); //重載等號操做符
如:
stack stkIntA, stkIntC; …
stack stkIntB(stkIntA);
stack stkIntD;
stkIntD = stkIntC;
stack的數據存取
stack.top(); //返回最後一個壓入棧元素
stack的大小
stack.empty(); //判斷堆棧是否爲空
stack.size(); //返回堆棧的大
list的講解綱要
list的簡介
list是一個雙向鏈表容器,可高效地進行插入刪除元素。
list不能夠隨機存取元素,因此不支持at.(pos)函數與[]操做符。
list使用以前的準備
#include
using namespace std;
list對象的默認構造
list採用模板類實現,list對象的默認構造形式:list lstT; 如:
list lstInt; //定義一個存放int的list容器。
list lstFloat; //定義一個存放float的list容器。
list lstString; //定義一個存放string的list容器。
…
//尖括號內還能夠設置指針類型或自定義類型。
list頭尾的添加移除操做
list.push_back(elem); //在容器尾部加入一個元素
list.pop_back(); //刪除容器中最後一個元素
list.push_front(elem); //在容器開頭插入一個元素
list.pop_front(); //從容器開頭移除第一個元素
list的數據存取
list.front(); //返回第一個元素。
list.back(); //返回最後一個元素。
list與迭代器
list.begin(); //返回容器中第一個元素的迭代器。
list.end(); //返回容器中最後一個元素以後的迭代器。
list.rbegin(); //返回容器中倒數第一個元素的迭代器。
list.rend(); //返回容器中倒數最後一個元素的後面的迭代器。
list對象的帶參數構造
list(beg,end); //構造函數將[beg, end)區間中的元素拷貝給自己。注意該區間是左閉右開的區間。
list(n,elem); //構造函數將n個elem拷貝給自己。
list(const list &lst); //拷貝構造函數。
list的賦值
list.assign(beg,end); //將[beg, end)區間中的數據拷貝賦值給自己。注意該區間是左閉右開的區間。
list.assign(n,elem); //將n個elem拷貝賦值給自己。
list& operator=(const list &lst); //重載等號操做符
list.swap(lst); // 將lst與自己的元素互換。
list的大小
list.size(); //返回容器中元素的個數
list.empty(); //判斷容器是否爲空
list.resize(num); //從新指定容器的長度爲num,若容器變長,則以默認值填充新位置。若是容器變短,則末尾超出容器長度的元素被刪除。
list.resize(num, elem); //從新指定容器的長度爲num,若容器變長,則以elem值填充新位置。若是容器變短,則末尾超出容器長度的元素被刪除。
list的插入
list.insert(pos,elem); //在pos位置插入一個elem元素的拷貝,返回新數據的位置。
list.insert(pos,n,elem); //在pos位置插入n個elem數據,無返回值。
list.insert(pos,beg,end); //在pos位置插入[beg,end)區間的數據,無返回值。
list的刪除
list.clear(); //移除容器的全部數據
list.erase(beg,end); //刪除[beg,end)區間的數據,返回下一個數據的位置。
list.erase(pos); //刪除pos位置的數據,返回下一個數據的位置。
lst.remove(elem); //刪除容器中全部與elem值匹配的元素。
list的反序排列
lst.reverse(); //反轉鏈表,好比lst包含1,3,5元素,運行此方法後,lst就包含5,3,1元素。
回顧
1、容器deque的使用方法
適合 在頭尾添加移除元素。使用方法與vector相似。
2、容器queue,stack的使用方法
適合隊列,堆棧的操做方式。
3、容器list的使用方法
適合在任意位置快速插入移除元素。
這一講,主要講解以下要點:
1、容器set/multiset的使用方法;
2、functor的使用方法;
3、pair的使用方法。
講解綱要
set/multiset的簡介
set是一個集合容器,其中所包含的元素是惟一的,集合中的元素按必定的順序排列。元素插入過程是按排序規則插入,因此不能指定插入位置。
set採用紅黑樹變體的數據結構實現,紅黑樹屬於平衡二叉樹。在插入操做和刪除操做上比vector快。
set不能夠直接存取元素。(不可使用at.(pos)與[]操做符)。
multiset與set的區別:set支持惟一鍵值,每一個元素值只能出現一次;而multiset中同一值能夠出現屢次。
不能夠直接修改set或multiset容器中的元素值,由於該類容器是自動排序的。若是但願修改一個元素值,必須先刪除原有的元素,再插入新的元素。
set/multiset使用以前的準備
#include
using namespace std;
set/multiset對象的默認構造
set採用模板類實現,set/multiset對象的默認構造形式:set setT; multiset multisetT; 如:
set setInt; //一個存放int的set容器。
set setFloat; //一個存放float的set容器。
set setString; //一個存放string的set容器。
multiset mulsetInt; //一個存放int的multi set容器。
multi set multisetFloat; //一個存放float的multi set容器。
multi set multisetString; //一個存放string的multi set容器。
…
//尖括號內能夠還設置各類指針類型或自定義類型。
set的插入與迭代器
set.insert(elem); //在容器中插入元素。
set.begin(); //返回容器中第一個數據的迭代器。
set.end(); //返回容器中最後一個數據以後的迭代器。
set.rbegin(); //返回容器中倒數第一個元素的迭代器。
set.rend(); //返回容器中倒數最後一個元素的後面的迭代器。
例如: set setInt;
setInt.insert(3); setInt.insert(1);setInt.insert(5);setInt.insert(2);
for(set::iterator it=setInt.begin(); it!=setInt.end(); ++it)
{ int iItem = *it; cout << iItem; //或直接使用cout << *it }
//這樣子便順序輸出 1 2 3 5。
疑問: 能不能在插入數值時,採用降序排列,而不是升序排列呢。
set<int,less > setIntA; //該容器是按升序方式排列元素。
set<int,greater> setIntB; //該容器是按降序方式排列元素。
set 至關於 set<int,less>。
less與greater中的int能夠改爲其它類型,該類型主要要跟set容納的數據類型一致。
疑問1:less<>與greater<>是什麼?
疑問2:若是set<>不包含int類型,而是包含自定義類型,set容器如何排序?
要解決如上兩個問題,須要瞭解容器的函數對象,也叫僞函數,英文名叫functor。
下面將講解什麼是functor,functor的用法。
函數對象functor的簡介
儘管函數指針被普遍用於實現函數回調,但C++還提供了一個重要的實現回調函數的方法,那就是函數對象。
functor,翻譯成函數對象,僞函數,算符,是重載了「()」操做符的普通類對象。從語法上講,它與普通函數行爲相似。
greater<>與less<>就是函數對象。
下面舉出greater的簡易實現原理。
struct greater
{
bool operator() (const int& iLeft, const int& iRight)
{
return (iLeft>iRight); //若是是實現less<int>的話,這邊 //是寫return (iLeft<iRight);
}
}
容器就是調用函數對象的operator()方法去比較兩個值的大小。
題目:學生包含學號,姓名屬性,現要求任意插入幾個學生對象到set容器中,使得容器中的學生按學號的升序排序。
//學生類
class CStudent
{
public:
CStudent(int iID, string strName)
{
m_iID = iID;
m_strName = strName;
}
int m_iID; //學號 string m_strName; //姓名
}
//爲保持主題鮮明,本類不寫拷貝構造函數,但你們仍要有考慮拷貝構造函數的習慣。
//函數對象
struct StuFunctor
{
bool operator() (const CStudent &stu1, const CStudent &stu2)
{
return (stu1.m_iID<stu2.m_iID);
}
}
//main函數
void main()
{
set<CStudent, StuFunctor> setStu;
setStu.insert(CStudent(3,「小張」));
setStu.insert(CStudent(1,「小李」));
setStu.insert(CStudent(5,「小王」));
setStu.insert(CStudent(2,「小劉」));
//此時容器setStu包含了四個學生對象,分別是按姓名順序的「小李」,「小劉」,「小張」,「小王」
}
函數對象functor的用法
set(const set &st); //拷貝構造函數
set& operator=(const set &st); //重載等號操做符
set.swap(st); //交換兩個集合容器
如:
set setIntA, setIntC;
…
set setIntB(setIntA);
set setIntD;
setIntD = setIntC;
set對象的拷貝構造與賦值
set(const set &st); //拷貝構造函數
set& operator=(const set &st); //重載等號操做符
set.swap(st); //交換兩個集合容器
如:
set setIntA, setIntC;
…
set setIntB(setIntA);
set setIntD;
setIntD = setIntC;
set的大小
set.size(); //返回容器中元素的數目
set.empty();//判斷容器是否爲空
set的刪除
set.clear(); //清除全部元素
set.erase(pos); //刪除pos迭代器所指的元素,返回下一個元素的迭代器。
set.erase(beg,end); //刪除區間[beg,end)的全部元素 ,返回下一個元素的迭代器。
set.erase(elem); //刪除容器中值爲elem的元素。
set的查找
set.find(elem); //查找elem元素,返回指向elem元素的迭代器。
set.count(elem); //返回容器中值爲elem的元素個數。對set來講,要麼是0,要麼是1。對multiset來講,值可能大於1。
set.lower_bound(elem); //返回第一個>=elem元素的迭代器。
set.upper_bound(elem); // 返回第一個>elem元素的迭代器。
set.equal_range(elem); //返回容器中與elem相等的上下限的兩個迭代器。上限是閉區間,下限是開區間,如[beg,end)。
以上函數返回兩個迭代器,而這兩個迭代器被封裝在pair中。
如下講解pair的含義與使用方法。
pair的簡介
pair譯爲對組,能夠將兩個值視爲一個單元。
pair<T1,T2>存放的兩個值的類型,能夠不同,如T1爲int,T2爲float。T1,T2也能夠是自定義類型。
pair.first是pair裏面的第一個值,是T1類型。
pair.second是pair裏面的第二個值,是T2類型。
pair的使用
例如 set setInt;
… //往setInt容器插入元素1,3,5,7,9
pair< set::iterator , set::iterator > pairIt = setInt.equal_range(5);
set::iterator itBeg = pairIt.first;
set::iterator itEnd = pairIt.second;
//此時 *itBeg==5 而 *itEnd == 7
回顧
1、容器set/multiset的使用方法;
紅黑樹的變體,查找效率高,插入不能指定位置,插入時自動排序。
2、functor的使用方法;
相似於函數的功能,可用來自定義一些規則,如元素比較規則。
3、pair的使用方法。
對組,一個總體的單元,存放兩個類型(T1,T2,T1可與T2同樣)的兩個元素。
容器map/multimap的使用方法
map/multimap的簡介
map是標準的關聯式容器,一個map是一個鍵值對序列,即(key,value)對。它提供基於key的快速檢索能力。
map中key值是惟一的。集合中的元素按必定的順序排列。元素插入過程是按排序規則插入,因此不能指定插入位置。
map的具體實現採用紅黑樹變體的平衡二叉樹的數據結構。在插入操做和刪除操做上比vector快。
map能夠直接存取key所對應的value,支持[]操做符,如map[key]=value。
multimap與map的區別:map支持惟一鍵值,每一個鍵只能出現一次;而multimap中相同鍵能夠出現屢次。multimap不支持[]操做符。
map/multimap使用以前的準備
#include
using namespace std;
map/multimap對象的默認構造
map/multimap採用模板類實現,對象的默認構造形式:
map<T1,T2> mapTT;
multimap<T1,T2> multimapTT;
如:map<int, char> mapA;
map<string,float> mapB;
//其中T1,T2還能夠用各類指針類型或自定義類型
map的插入與迭代器
map.insert(…); //往容器插入元素,返回pair<iterator,bool>
在map中插入元素的三種方式:
假設 map<int, string> mapStu;
1、經過pair的方式插入對象
mapStu.insert( pair<int,string>(3,「小張」) );
2、經過value_type的方式插入對象
mapStu.insert( map<int,string>::value_type(1,「小李」) );
3、經過數組的方式插入值
mapStu[3] = 「小劉";
mapStu[5] = 「小王";
…
第三種方法很是直觀,但存在一個性能的問題。插入3時,先在mapStu中查找主鍵爲3的項,若沒發現,則將一個鍵爲3,值爲初始化值的對組插入到mapStu中,而後再將值修改爲「小劉」。若發現已存在3這個鍵,則修改這個鍵對應的value。
string strName = mapStu[2]; //取操做或插入操做
只有當mapStu存在2這個鍵時纔是正確的取操做,不然會自動插入一個實例,鍵爲2,值爲初始化值。
前兩種方法,採用的是insert()方法,該方法返回值爲pair<iterator,bool>
pair< map<int,string>::iterator , bool > pairResult = mapStu.insert( pair<int,string>(3,「小張」) );
若是插入成功,(pairResult.first)->first3, (pairResult.first)->second"小張" pairResult.second==true。
map<T1,T2,less > mapA; //該容器是按鍵的升序方式排列元素。未指定函數對象,默認採用less函數對象。
map<T1,T2,greater> mapB; //該容器是按鍵的降序方式排列元素。
less與greater 能夠替換成其它的函數對象functor。
可編寫自定義函數對象以進行自定義類型的比較,使用方法與set構造時所用的函數對象同樣。
map.begin(); //返回容器中第一個數據的迭代器。
map.end(); //返回容器中最後一個數據以後的迭代器。
map.rbegin(); //返回容器中倒數第一個元素的迭代器。
map.rend(); //返回容器中倒數最後一個元素的後面的迭代器。
map對象的拷貝構造與賦值
map(const map &mp); //拷貝構造函數
map& operator=(const map &mp); //重載等號操做符
map.swap(mp); //交換兩個集合容器
如:
map<T1,T2> mapIntA, mapIntC;
…
map<T1,T2> mapIntB(mapIntA);
map<T1,T2> mapIntD;
mapIntD = mapIntC;
map的大小
map.size(); //返回容器中元素的數目
map.empty();//判斷容器是否爲空
map的刪除
map.clear(); //刪除全部元素
map.erase(pos); //刪除pos迭代器所指的元素,返回下一個元素的迭代器。
map.erase(beg,end); //刪除區間[beg,end)的全部元素 ,返回下一個元素的迭代器。
map.erase(keyElem); //刪除容器中key爲keyElem的對組。
map的查找
map.find(key); 查找鍵key是否存在,若存在,返回該鍵的元素的迭代器;若不存在,返回map.end();
map.count(keyElem); //返回容器中key爲keyElem的對組個數。對map來講,要麼是0,要麼是1。對multimap來講,值可能大於1。
map<int,string>::iterator it=mapStu.find(3);
if(it == mapStu.end())
{
//沒找到
}
else
{
//找到了
pair<int, string> pairStu = *it;
int iID = pairStu.first; //或 int iID = it->first;
string strName = pairStu.second; //或 string strName = it->second;
}
map.lower_bound(keyElem); //返回第一個key>=keyElem元素的迭代器。
map.upper_bound(keyElem); // 返回第一個key>keyElem元素的迭代器。
例如: mapStu是用map<int,string>聲明的容器,已包含{1,「小李」}{3,「小張」}{5,「小王」}{7,「小趙」}{9,「小陳」}元素。map<int,string>::iterator it;
it = mapStu.lower_bound(5); //it->first5 it->second"小王"
it = mapStu.upper_bound(5); //it->first7 it->second"小趙"
it = mapStu.lower_bound(6); //it->first7 it->second"小趙"
it = mapStu.upper_bound(6); //it->first7 it->second"小趙"
map.equal_range(keyElem); //返回容器中key與keyElem相等的上下限的兩個迭代器。上限是閉區間,下限是開區間,如[beg,end)。
以上函數返回兩個迭代器,而這兩個迭代器被封裝在pair中。
例如 map<int,string> mapStu;
… //往mapStu容器插入元素{1,「小李」}{3,「小張」}{5,「小王」}{7,「小趙」}{9,「小陳」}
pair< map<int,string>::iterator , map<int,string>::iterator > pairIt = mapStu.equal_range(5);
map<int, string>::iterator itBeg = pairIt.first;
map<int, string>::iterator itEnd = pairIt.second;
//此時 itBeg->first==5 , itEnd->first == 7,
itBeg->second==「小王」, itEnd->second==「小趙」
Multimap例子
struct userdevice{
string m_devicename;
long m_deviceid;
int m_devicePopedom;
};
typedef multimap<string,userdevice> USERTABLE;
typedef USERTABLE::const_iterator CIT;
typedef pair<CIT, CIT> Range;
本 講 要 點
1、容器的共通能力;
2、各個容器的使用時機;
3、經常使用算法(Algorithm)的用法介紹。
容器的共通能力
全部容器提供的都是值(value)語意,而非引用(reference)語意。容器執行插入元素的操做時,內部實施拷貝動做。因此STL容器內存儲的元素必須可以被拷貝(必須提供拷貝構造函數)。
除了queue與stack外,每一個容器都提供可返回迭代器的函數,運用返回的迭代器就能夠訪問元素。
一般STL不會丟出異常。要求使用者確保傳入正確的參數。
每一個容器都提供了一個默認構造函數跟一個默認拷貝構造函數。
如已有容器vecIntA。
vector vecIntB(vecIntA); //調用拷貝構造函數,複製vecIntA到vecIntB中。
與大小相關的操做方法(c表明容器):
c.size(); //返回容器中元素的個數
c.empty(); //判斷容器是否爲空
比較操做(c1,c2表明容器):
c1 == c2 判斷c1是否等於c2
c1 != c2 判斷c1是否不等於c2
c1 = c2 把c2的全部元素指派給c1
各個容器的使用時機
Vector的使用場景:好比軟件歷史操做記錄的存儲,咱們常常要查看歷史記錄,好比上一次的記錄,上上次的記錄,但卻不會去刪除記錄,由於記錄是事實的描述。
deque的使用場景:好比排隊購票系統,對排隊者的存儲能夠採用deque,支持頭端的快速移除,尾端的快速添加。若是採用vector,則頭端移除時,會移動大量的數據,速度慢。
vector與deque的比較:
一:vector.at()比deque.at()效率高,好比vector.at(0)是固定的,deque的開始位置倒是不固定的。
二:若是有大量釋放操做的話,vector花的時間更少,這跟兩者的內部實現有關。
三:deque支持頭部的快速插入與快速移除,這是deque的優勢。
list的使用場景:好比公交車乘客的存儲,隨時可能有乘客下車,支持頻繁的不確實位置元素的移除插入。
set的使用場景:好比對手機遊戲的我的得分記錄的存儲,存儲要求從高分到低分的順序排列。
map的使用場景:好比按ID號存儲十萬個用戶,想要快速要經過ID查找對應的用戶。二叉樹的查找效率,這時就體現出來了。若是是vector容器,最壞的狀況下可能要遍歷完整個容器才能找到該用戶。
算法(Algorithm)的簡介
算法部分主要由頭文件,和組成。
是全部STL頭文件中最大的一個,其中經常使用到的功能範圍涉及到比較、交換、查找、遍歷操做、複製、修改、反轉、排序、合併等等。
體積很小,只包括幾個在序列上面進行簡單數學運算的模板函數,包括加法和乘法在序列上的一些操做。
中則定義了一些模板類,用以聲明函數對象。
STL提供了大量實現算法的模版函數,只要咱們熟悉了STL以後,許多代碼能夠被大大的化簡,只須要經過調用一兩個算法模板,就能夠完成所須要的功能,從而大大地提高效率。
算法(Algorithm)使用以前的準備
#include
#include
#include
using namespace std;
算法(Algorithm)的講解大綱
經常使用的查找算法:
adjacent_find()( adjacent 是鄰近的意思),binary_search(),count(),
count_if(),equal_range(),find(),find_if()。
經常使用的排序算法:
merge(),sort(),random_shuffle()(shuffle是洗牌的意思) ,reverse()。
經常使用的拷貝和替換算法:
copy(), replace(),
replace_if(),swap()
經常使用的算術和生成算法:
accumulate()( accumulate 是求和的意思),fill(),。
經常使用的集合算法:
set_union(),set_intersection(),
set_difference()。
經常使用的遍歷算法:
for_each(), transform()( transform 是變換的意思)
經常使用的查找算法
adjacent_find(): 在iterator對標識元素範圍內,查找一對相鄰重複元素,找到則返回指向這對元素的第一個元素的迭代器。不然返回past-the-end。
例如:vecInt是用vector聲明的容器,現已包含1,2,2,4,5元素。
vector::iterator it=adjacent_find(vecInt.begin(),vecInt.end());
此時 *it == 2
binary_search: 在有序序列中查找value,找到則返回true。注意:在無序序列中,不可以使用。
例如: setInt是用set聲明的容器,現已包含1,3,5,7,9元素。
bool bFind = binary_search(setInt.begin(),setInt.end(),5);
此時 bFind == true
count: 利用等於操做符,把標誌範圍內的元素與輸入值比較,返回相等的個數。
count_if: 利用輸入的函數,對標誌範圍內的元素進行比較操做,返回結果爲true的個數。
例如:vecInt是用vector聲明的容器,已包含1,3,5,7,9元素,現要求求出大於等於3的元素個數
//先定義比較函數
bool GreaterThree(int iNum)
{
if(iNum>=3)
{
return true;
}
else
{
return false;
}
}
int iCount = count_if(vecIntA.begin(), vecIntA.end(), GreaterThree);
//此時iCount == 4
equal_range: 返回一對iterator,第一個表示lower_bound,第二個表示upper_bound。
find: 利用底層元素的等於操做符,對指定範圍內的元素與輸入值進行比較。當匹配時,結束搜索,返回該元素的迭代器。
例如: vecInt是用vector聲明的容器,已包含1,3,5,7,9
vector::iterator it = find(vecInt.begin(),vecInt.end(),5);
此時 *it == 5
find_if: 使用輸入的函數代替等於操做符執行find。返回被找到的元素的迭代器。
例如:vecInt是用vector聲明的容器,已包含1,3,5,3,9元素。現要找出第一個大於等於3的元素的迭代器。
vector::iterator it = find_if(vecInt.begin(),vecInt.end(),GreaterThree);
此時 *it==3, *(it+1)==5, *(it+2)==3, *(it+3)==9
經常使用的排序算法
如下是排序和通用算法:提供元素排序策略
merge: 合併兩個有序序列,存放到另外一個序列。
例如:vecIntA,vecIntB,vecIntC是用vector聲明的容器,vecIntA已包含1,3,5,7,9元素,vecIntB已包含2,4,6,8元素
vecIntC.resize(9); //擴大容量
merge(vecIntA.begin(),vecIntA.end(),vecIntB.begin(),vecIntB.end(),vecIntC.begin());
此時vecIntC就存放了按順序的1,2,3,4,5,6,7,8,9九個元素
sort: 以默認升序的方式從新排列指定範圍內的元素。若要改排序規則,能夠輸入比較函數。
例如: vecInt是用vector聲明的容器,已包含2,1,4,3,6,5元素
sort(vecInt.begin(),vecInt.end()); 此時,vecInt包含了1,2,3,4,5,6元素。
若是vector,T是自定義類型,則要提供T類型的比較函數。
random_shuffle: 對指定範圍內的元素隨機調整次序。
reverse: 對指定範圍內元素從新反序排序。
經常使用的拷貝和替換算法
copy: 複製序列
例如:vecIntA,vecIntB是用vector聲明的對象,vecIntA已包含1,3,5,7,9元素。
vecIntB.resize(5);
copy(vecIntA.begin(),vecIntA.end(),vecIntB.begin());
此時vecIntB也包含了1,3,5,7,9元素
replace(beg,end,oldValue,newValue):將指定範圍內的全部等於oldValue的元素替換成newValue。
replace_if : 將指定範圍內全部操做結果爲true的元素用新值替換。
用法舉例:replace_if(vecIntA.begin(),vecIntA.end(),GreaterThree,newVal)
其中 vecIntA是用vector聲明的容器
GreaterThree 函數的原型是 bool GreaterThree(int iNum)
swap: 交換兩個容器的元素
經常使用的算術與生成算法
accumulate: 對指定範圍內的元素求和,而後結果再加上一個由val指定的初始值。
fill: 將輸入值賦給標誌範圍內的全部元素。
算法(Algorithm)的使用方法
set_union: 構造一個有序序列,包含兩個有序序列的並集。
set_intersection: 構造一個有序序列,包含兩個有序序列的交集。
set_difference: 構造一個有序序列,該序列保留第一個有序序列中存在而第二個有序序列中不存在的元素。
經常使用的遍歷算法
for_each: 用指定函數依次對指定範圍內全部元素進行迭代訪問。該函數不得修改序列中的元素。
transform: 與for_each相似,遍歷全部元素,但可對容器的元素進行修改
回顧
1、容器的共通能力;
2、各個容器的使用時機;
3、經常使用算法(Algorithm)的用法介紹
查找,排序,拷貝,替換,算術,生成,關係,集合,遍歷。