學了C++不會STL,簡直少了左膀右臂

什麼是STL :

容器(Container):
是一種數據結構,如list,vector,和deques ,以模板類的方法提供。爲了訪問容器中的數據,可以使用由容器類輸出的迭代器;
迭代器(Iterator):
提供了訪問容器中對象的方法。例如,可以使用一對迭代器指定list或vector中的一定範圍的對象。迭代器就如同一個指針。事實上,C++的指針也是一種迭代器。但是,迭代器也可以是那些定了operator*()以及其他類似於指針的操作符地方法的類對象;
算法(Algorithm):
是用來操作容器中的數據的模板函數。例如,STL用sort()來對一個vector中的數據進行排序,用find()來搜索一個list中的對象,函數本身與他們操作的數據的結構和類型無關,因此他們可以在從簡單數組到高度複雜容器的任何數據結構上使用;
仿函數(Functor)
適配器(Adaptor)
分配器(allocator)

仿函數、適配器、與分配器用的比較少,甚至沒用過!在這裏不做說明,有興趣可以自己學習一下,那個東西C++軟件工程可能用的比較多。

一、迭代器(Iterator)

背景:指針可以用來遍歷存儲空間連續的數據結構,但是對於存儲空間費連續的,就需要尋找一個行爲類似指針的類,來對非數組的數據結構進行遍歷。
定義:迭代器是一種檢查容器內元素並遍歷元素的數據類型。
迭代器提供對一個容器中的對象的訪問方法,並且定義了容器中對象的範圍。
迭代器(Iterator)是指針(pointer)的泛化,它允許程序員用相同的方式處理不同的數據結構(容器)。
(1)迭代器類似於C語言裏面的指針類型,它提供了對對象的間接訪問。
(2)指針是C語言中的知識點,迭代器是C++中的知識點。指針較靈活,迭代器功能較豐富。
(3)迭代器提供一個對容器對象或者string對象的訪問方法,並定義了容器範圍。

迭代器和指針的區別:
容器和string有迭代器類型同時擁有返回迭代器的成員。如:容器有成員begin和end,其中begin成員複製返回指向第一個元素的迭代器,而end成員返回指向容器尾元素的下一個位置的迭代器,也就是說end指示的是第一個不合法地址,所以end返回的是尾後迭代器。

容器迭代器的使用
每種容器類型都定義了自己的迭代器類型,如vector:vector< int>:: iterator iter;//定義一個名爲iter的變量,數據類型是由vector< int>定義的iterator 類型。簡單說就是容器類定義了自己的iterator類型,用於訪問容器內的元素。每個容器定義了一種名爲iterator的類型,這種類型支持迭代器的各種行爲。
我麼們先講一下各種迭代器的類型,在講容器所用的迭代器類型,就可以明白怎麼操作。

常見迭代器類型如下:

所有迭代器 操作
p++ 後置自增迭代器
++p 前置自增迭代器
輸入迭代器 操作介紹
*p 復引用迭代器,作爲右值
p=p1 將一個迭代器賦給另一個迭代器(迭代器指向地址值)
p==p1 比較迭代器的相等性(比較地址)
p!=p1 比較迭代器的不等性
輸出迭代器 操作
*p 復引用迭代器,作爲左值
p=p1 將一個迭代器賦給另一個迭代器
正向迭代器 提供輸入輸出迭代器的所有功能
雙向迭代器 操作
–p 前置自減迭代器
p– 後置自減迭代器
隨機迭代器
p+=i 將迭代器遞增i位
p-=i 將迭代器遞減i位
p+i 在p位加i位後的迭代器
p-i 在p位減i位後的迭代器
p[i] 返回p位元素偏離i位的元素引用
p<p1 如果迭代器p的位置在p1前,返回true,否則返回false
p<=p1 p的位置在p1的前面或同一位置時返回true,否則返回false
p>p1 如果迭代器p的位置在p1後,返回true,否則返回false
p>=p1 p的位置在p1的後面或同一位置時返回true,否則返回false

只有順序容器和關聯容器支持迭代器遍歷,各容器支持的迭代器的類別如下:

容器 支持的迭代器類別 說明
vector 隨機訪問 一種隨機訪問的數組類型,提供了對數組元素進行快速隨機訪問以及在序列尾部進行快速的插入和刪除操作的功能。可以再需要的時候修改其自身的大小
deque 隨機訪問 一種隨機訪問的數組類型,提供了序列兩端快速進行插入和刪除操作的功能。可以再需要的時候修改其自身的大小
list 雙向 一種不支持隨機訪問的數組類型,插入和刪除所花費的時間是固定的,與位置無關。
set 雙向 一種隨機存取的容器,其關鍵字和數據元素是同一個值。所有元素都必須具有惟一值。
multiset 雙向 一種隨機存取的容器,其關鍵字和數據元素是同一個值。可以包含重複的元素。
map 雙向 一種包含成對數值的容器,一個值是實際數據值,另一個是用來尋找數據的關鍵字。一個特定的關鍵字只能與一個元素關聯。
multimap 雙向 一種包含成對數值的容器,一個值是實際數據值,另一個是用來尋找數據的關鍵字。一個關鍵字可以與多個數據元素關聯。
stack 不支持 適配器容器類型,用vector,deque或list對象創建了一個先進後出容器
queue 不支持 適配器容器類型,用deque或list對象創建了一個先進先出容器
priority_queue 不支持 適配器容器類型,用vector或deque對象創建了一個排序隊列

二、容器

所有容器都支持自定義數據類型,就是結構體。

vector

使用此容器需在程序前加上頭文件#include< vector >。
vector可理解爲變長數組,基於倍增思想。當以已申請vector長度爲m時,若實際長度n=m,則申請長度爲2m的數組,將內容轉移至新地址上,並釋放舊空間;刪除元素時,若n<=m/4,則釋放一半空間。
vector容器能像數組一樣隨機訪問第i個數a[i],但不支持隨機插入.

#include<vector>       //頭文件
vector<int> a;  定義了一個int類型的vector容器a
vector<int> b[100];定義了一個int類型的vector容器b組
struct rec{···};
vector<rec> c;           /定義了一個rec類型的vector容器c
vector<int>::iterator it;           //vector的迭代器,與指針類似

具體操作如下:

	a.size()            //返回實際長度(元素個數),O(1)複雜度
    a.empty()           //容器爲空返回1,否則返回0,O(1)複雜度
    a.clear()           //把vector清空
    a.begin()           //返回指向第一個元素的迭代器,*a.begin()與a[0]作用相同
    a.end()             //越界訪問,指向vector尾部,指向第n個元素再往後的邊界
    a.front()           //返回第一個元素的值,等價於*a.begin和a[0]
    a.back()            //返回最後一個元素的值,等價於*--a.end()和a[size()-1]
    a.push_back(x)      //把元素x插入vector尾部
    a.pop_back()        //刪除vector中最後一個元素

迭代器使用與指針類似,可如下遍歷整個容器

for ( vector<int>::iterator it=a.begin() ; it!=a.end() ; it++ )

queue

循環隊列queue需使用頭文件< queue >

queue<int> q;   //定義了一個int類型的隊列容器q
struct rec{···};queue<rec> q;      //定義了一個rec類型的隊列容器q
q.push(x);           //從隊尾使元素x入隊,O(1)
q.pop(x);            //使隊首元素出隊,O(1)
int x=q.front();     //詢問隊首元素的值,O(1)
int y=q.back();      //詢問隊尾元素的值,O(1)

priority_queue

優先隊列priority_queue可理解爲一個大根二叉堆,必須定義“小於號”,而int,string本身就能比較。同樣需要頭文件< queue >。
其定義方式與queue相似。

priority_queue<int> q;  由大到小
priority_queue<pair<int,int>> q; //pair是一個數對,由first和scond兩個元素構成,按照第一個排序
priority_queue<int, vector<int>, greater<int> >qi2; //由小到大,小根堆,vector<int>是適配器,不用知道很詳細,記住就行
struct rec  //舉個栗子
{
	int a,b,c;
	bool operator<(const rec&w)
	{
		if(a==w.a) return b==w.b?c<w.c:b<w.b;
		return a<w.a;
	}
};
priority_queue<rec> q; 如果不寫重載函數,會出錯,他不知道怎麼排序
q.push(x);         //插入   O(log n)
q.pop();           //刪除堆頂元素    O(log n)
q.top();           //查詢堆頂元素   O(1)

可通過插入元素的相反數取出時再取反,或重載“小於號”的方式實現小根堆,通過懶惰刪除法實現隨機刪除操作。

deque

雙端隊列,是一個支持在兩端高效插入或刪除元素的連續線性存儲空間,可像數組一樣隨機訪問,使用前加頭文件< deque >。

q.begin()/q.end()              //頭/尾迭代器,與vector類似
q.front()/q.back()             //頭/尾元素,與queue類似
q.push_back(x)/q.push_front(x) //從隊尾/隊頭入隊
q.pop_back(x)/q.pop_front(x)   //從隊尾/隊頭出隊
q.clear()                      //清空隊列

定義方式

deque<類型> 名稱

ps:clear複雜度爲O(n),其餘爲O(1)。

set/multiset

兩容器相似,但set爲有序集合,元素不能重複,multiset爲有序多重集合,可包含若干相等的元素,內部通過紅黑樹實現,支持的函數基本相同,同樣必須定義“小於號”運算符,頭文件爲< set >。
其迭代器不支持隨機訪問,支持星號(*)結束引用,僅支持 ++ 、-- 兩個與算術有關的操作。迭代器it++,則指向從小到大排序的結果中排在it下一名的元素,兩操作時間複雜度均爲O(log n)。

q.size()  //返回容器內元素個數
q.empty()  //判斷容器是否爲空
q.clear() //清空容器
q.begin()/q.end()          //作用與上文幾種容器類似
q.insert(x)                //將元素x插入集合中,O(log n)
q.find(x)                  //查找等於x的元素,返回其迭代器,無則返回q.end(),O(log n)
q.lower_bound(x)           //查找>=x的元素中最小的一個,返回指向該元素的迭代器
q.upper_bound(x)           //查找>x的元素中最小的一個,返回指向該元素的迭代器
q.erase(it)                //刪除迭代器it指向的元素,O(log n)
q.erase(x)                 //刪除所有等於x的元素,複雜度爲O(k+log n),k爲被刪除的元素個數
q.count(x)                 //返回等於x的元素個數,O(k+log n),k爲元素x的個數

定義方式


 
set<int> demo 定義一個類型爲int的set容器
struct  rec
{
    int a,b,c;
    bool operator<(const rec&w)
    {
        if(a==w.a) return b==w.b?c<w.c:b<w.b;
        return a<w.a;
    }
};
  set<rec> ob;  一樣所有排序的容器不重載就出錯

map/multimap

map/multimap映射容器的元素數據是由一個Key和一個Value成的,key與映照value之間具有一一映照的關係。

map/multimap容器的數據結構也採用紅黑樹來實現的,map插入元素的鍵值不允許重複,類似multiset,multimap的key可以重複。比較函數只對元素的key進行比較,元素的各項數據只能通過key檢索出來。雖然map與set採用的都是紅黑樹的結構,但跟set的區別主要是set的一個鍵值和一個映射數據相等,Key=Value。

map<first,second> a;
//map,會按照first(鍵值)排序(查找也是);

map/multimap用法
頭文件

#include< map >

map成員函數

begin()				 //返回指向 map 頭部的迭代器
clear(// 刪除所有元素
count() 			//返回指定元素出現的次數
empty()				// 如果 map 爲空則返回 true
end() 				//返回指向 map 末尾的迭代器
erase()				// 刪除一個元素
find()				// 查找一個元素
insert()			 //插入元素
key_comp() 			//返回比較元素 key 的函數
lower_bound() 		//返回鍵值>=給定元素的第一個位置
max_size() 			//返回可以容納的最大元素個數
rbegin() 			//返回一個指向 map 尾部的逆向迭代器
rend() 				//返回一個指向 map 頭部的逆向迭代器
size() 				//返回 map 中元素的個數
swap()				 //交換兩個 map

創建map對象

#include<iostream>
#include<map>
using namespace std;
map<int,char>mp;//定義map容器 

創建結構體map對象

struct student{
int birth;
string name;
};
int id;
typedef map<int,student> Student;// 這裏相當於給map<int,student> 起了個別名Student,後續代碼均可以用student代替map<int,student> 使用。

插入結構體對象
接上文代碼

Stduent  a; 
cin>>id>>student.birth>>student.name;
a.insert(make_pair(id,student));
   

棧(stack)

1.定義:
棧是一種只能在某一端插入和刪除數據的特殊線性表。他按照先進先出的原則存儲數據,先進的數據被壓入棧底,最後進入的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最後被壓入棧的,最先彈出)。因此棧也稱先進後出表。
允許進行插入刪除操作的一端稱爲棧頂,另一端稱爲棧底。棧底固定,棧頂浮動。插入元素稱爲進棧,刪除一個元素稱爲進棧,棧內元素爲零稱爲空棧。
2.stack成員函數

   bool empty ( ) ————>棧爲空返回true,否則返回falsevoid pop ( ) ————>刪除棧頂元素,出棧;
   void push(const TYPE&value)————> 插入新元素value,放置在棧頂進棧;TYPE:類型intchar…;
   size_type size ( ) ————> 返回堆棧中元素個數;(注意注意!!!!切不可賦值給int ,很容易超過int的範圍
   TYPE&top()————> 查看當前棧頂元素;

List

定義:List類表示可通過索引訪問的對象的強類型列表,提供用於對列表進行搜索、排序和操作的方法。
作用:
泛型最常見的用途是泛型集合
我們在創建列表類時,列表項的數據類型可能是int,string或其它類型,如果對列表類的處理方法相同,
就沒有必要事先指定數據類型,留待列表類實例化時再指定。相當於把數據類型當成參數,這樣可以最
大限度地重用代碼,保護類型的安全以及提高性能。
定義 list<類型> 名稱
成員函數

   l.begin()	將迭代器返回到開頭(Return iterator to beginning)
   l.end()	將迭代器返回到最後(Return iterator to end)
   l.rbegin()	Return reverse iterator to reverse beginning
   l.rend()	Return reverse iterator to reverse end
   l.l.empty()	檢查容器是否爲空
   l.size()	返回當前容器內元素個數
   l.max_size()	返回當前容器能容納的最大元素數量
   l.front()	訪問第一個元素
   l.back()	訪問最後一個元素
   l.push_front()	將元素插入到開頭
   l.pop_front()	刪除第一個元素
   l.push_back()	將元素插入到最後
   l.pop_back()	刪除最後一個元素
   l.insert()	插入元素
   l.erase()	刪除元素
   l.swap()	交換兩個 list 內容
   l.resize	()改變容器大小
   l.clear()	刪除容器所有內容

bitset

bitset可看作一個多位二進制數,每8位佔用1個字節,相當於採用了狀態壓縮的二進制數組,並支持基本的位運算。一般以32位整數的運算次數爲基準估算運行時間,n位bitset執行一次的位運算複雜度可視爲n/32,效率較高。頭文件< bitset >。
同樣具有~,&,|,^,<<,>>操作符,==,!=可比較二進制數是否相等

bitset<10000> q;      //聲明一個10000位的二進制數
q[k]                  //表示q的第k位,可取值,賦值,最低位爲q[0]
q.count()             //返回有多少位1
q.none()              //所有位都爲0則返回true,至少1位爲1則返回false
q.any()               //所有位都爲0則返回false,至少1位爲1則返回true,與函數none相反
q.set()               //把所有位變爲1
q.set(k,v)            //把第k位變爲v,即q[k]=v
q.reset()             //把所有位變爲0
q.reset(k)            //把第k位變爲0,即q[k]=0
q.flip()              //把所有位取反,即s=~s
q.flip(k)             //把第k位取反,即q[k]^=1

三、算法

查找算法(9個):判斷容器中是否包含某個值

(可以去看看C++primer學學別的,但是我認爲太多了沒必要)
1.count:
利用等於操作符,把標誌範圍內的元素與輸入值比較,返回相等元素個數。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int a[14]={0,1,2,3,4,5,6,7,7,7,7,7,7,8};
    cout<<count(a,a+14,7)<<endl;
    vector<int> demo;
    for(int i=0;i<10;i++)
        demo.push_back(i);
    demo.push_back(1);
    cout<<count(demo.begin(),demo.end(),1)<<endl;
}
//運行結果 6 2;

2.count_if:
利用輸入的操作符,對標誌範圍內的元素進行操作,返回結果爲true的個數。

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a)
{
    return (a>1);
}
int main()
{
    int a[14]={0,1,2,3,4,5,6,7,7,7,7,7,7,8};
  int po=count_if(a,a+14,cmp);
   cout<<po<<endl;
    vector<int> demo;
    for(int i=0;i<10;i++)
        demo.push_back(i);
    demo.push_back(1);
   int poi=count_if(demo.begin(),demo.end(),cmp);
    cout<<poi<<endl;
}// 運行結果   8 12
//看到網上大佬的代碼寫的比較深奧,特地去查了查書,我這樣用沒毛病的。

補充:捕獲值列表,是允許我們在Lambda表達式的函數體中直接使用這些值,捕獲值列表能捕獲的值是所有在此作用域可以訪問的值,包括這個作用域裏面的臨時變量,類的可訪問成員,全局變量。捕獲值的方式分兩種,一種是按值捕獲,一種是按引用捕獲。顧名思義,按值捕獲是不改變原有變量的值,按引用捕獲是可以在Lambda表達式中改變原有變量的值。

[捕獲值列表]:

1、空。沒有使用任何函數對象參數。
2、=。函數體內可以使用Lambda所在作用範圍內所有可見的局部變量(包括Lambda所在類的this),並且是值傳遞方式(相當於編譯器自動爲我們按值傳遞了所有局部變量)。
3、&。函數體內可以使用Lambda所在作用範圍內所有可見的局部變量(包括Lambda所在類的this),並且是引用傳遞方式(相當於編譯器自動爲我們按引用傳遞了所有局部變量)。
4、this。函數體內可以使用Lambda所在類中的成員變量。
5、a。將a按值進行傳遞。按值進行傳遞時,函數體內不能修改傳遞進來的a的拷貝,因爲默認情況下函數是const的。要修改傳遞進來的a的拷貝,可以添加mutable修飾符。
6、&a。將a按引用進行傳遞。
7、a, &b。將a按值進行傳遞,b按引用進行傳遞。
8、=,&a,&b。除a和b按引用進行傳遞外,其他參數都按值進行傳遞。
9、&, a, b。除a和b按值進行傳遞外,其他參數都按引用進行傳遞。

3.equal_range:
功能類似equal,返回一對iterator,第一個表示lower_bound,第二個表示upper_bound。

  #include<iostream>
    #include<algorithm>
    using namespace std;
    bool cmp(int a)
    {
        return (a>1);
    }
    int main()
    {
     //   int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};
        //equal_range(a,a+14,auto po);
        vector<int> demo;
        for(int i=0; i<10; i++)  demo.push_back(i);
        demo.push_back(1);
       cout<<*equal_range(demo.begin(),demo.end(),7).first<<endl;
       cout<<*equal_range(demo.begin(),demo.end(),7).second<<endl;
       cout<<equal_range(demo.begin(),demo.end(),7).first-demo.begin()<<endl;
       cout<<equal_range(demo.begin(),demo.end(),7).second-equal_range(demo.begin(),demo.end(),7).first<<endl;
    }
    //也可以加cmp函數,同樣適用於數組,在下文中不再舉出數組的例子

4.find:
利用底層元素的等於操作符,對指定範圍內的元素與輸入值進行比較。當匹配時,結束搜索,返回該元素的一個InputIterator。

補充
InputIterator是用於輸入的Iterator
OutputIterator是用於輸出的Iterator
ForwardIterator是InputIterator,同時可以保證++運算不會使之失效
RandomIterator是ForwardIterator,同時具有+,-,+=,-=等運算及各種比較操作

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
   int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};
    vector<int> demo;
    for(int i=0; i<14; i++)  demo.push_back(a[i]);
    demo.push_back(1);
    cout<<find(demo.begin(),demo.end(),8)-demo.begin()<<endl;
} //可以直接取地址獲取值。

5.find_end:
在指定範圍內查找"由輸入的另外一對iterator標誌的第二個序列"的最後一次出現。找到則返回最後一對的第一個ForwardIterator,否則返回輸入的"另外一對"的第一個ForwardIterator。重載版本使用用戶輸入的操作符代替等於操作。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
   int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};
    vector<int> demo;
    for(int i=0; i<14; i++)  demo.push_back(a[i]);
    demo.push_back(1);
    cout<<find_end(demo.begin(),demo.end(),a+2,a+3)-demo.begin()<<endl;
}

6.find_first_of:
在指定範圍內查找"由輸入的另外一對iterator標誌的第二個序列"中任意一個元素的第一次出現。重載版本中使用了用戶自定義操作符。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
   int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};
    vector<int> demo;
    for(int i=0; i<14; i++)  demo.push_back(a[i]);
    demo.push_back(1);
    cout<<find_first_of(demo.begin(),demo.end(),a+2,a+3)-demo.begin()<<endl;
}

7.find_if:
使用輸入的函數代替等於操作符執行find。返回的是迭代器,爲了是大家更明白的理解,減去第一個元素的位置,就相當於得到了下標;

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int w)   {
    return w>5;
}
int main()
{
   int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};
    vector<int> demo;
    for(int i=0; i<14; i++)  demo.push_back(a[i]);
   cout<< find_if(demo.begin(),demo.end(),cmp)-demo.begin();
}

8.lower_bound:
返回一個ForwardIterator,指向在有序序列範圍內的可以插入指定值而不破壞容器順序的第一個位置。重載函 數使用自定義比較操作。
在一個有序的範圍內時間複雜度爲log2n,普遍適用於二分算法。
跟3.equal_range的用法一樣不過這個返回的是first
9.upper_bound:
返回一個ForwardIterator,指向在有序序列範圍內插入value而不破壞容器順序的最後一個位置,該位置標誌 一個大於value的值。重載函數使用自定義比較操作。跟3.equal_range的用法一樣不過這個返回的是second;

排序和通用算法(7個):提供元素排序策略

  1. inplace_merge:

    合併兩個有序序列,結果序列覆蓋兩端範圍。重載版本使用輸入的操作進行排序。

  2. merge:

    合併兩個有序序列,存放到另一個序列。重載版本使用自定義的比較。 nth_element:
    將範圍內的序列重新排序,使所有小於第n個元素的元素都出現在它前面,而大於它的都出現在後面。重載版本使用自定義的比較操作。

  3. partial_sort:

    對序列做部分排序,被排序元素個數正好可以被放到範圍內。重載版本使用自定義的比較操作。

  4. partial_sort_copy:

    與partial_sort類似,不過將經過排序的序列複製到另一個容器。 partition:
    對指定範圍內元素重新排序,使用輸入的函數,把結果爲true的元素放在結果爲false的元素之前。 random_shuffle:
    對指定範圍內的元素隨機調整次序。重載版本輸入一個隨機數產生操作。 reverse:
    將指定範圍內元素重新反序排序。 reverse_copy: 與reverse類似,不過將結果寫入另一個容器。

  5. rotate:

將指定範圍內元素移到容器末尾,由middle指向的元素成爲容器第一個元素。

  1. rotate_copy:

    與rotate類似,不過將結果寫入另一個容器。

  2. sort:(常用,相信大家都不陌生)

    以升序重新排列指定範圍內的元素。重載版本使用自定義的比較操作。

 sort(首地址,第一個不合法地址(即末地址+1),cmp)//cmp可以缺省
 bool cmp()//可以用到結構體上 
 {
    	return (); 
  } 
        
  1. stable_sort:

    與sort類似,不過保留相等元素之間的順序關係。 stable_partition:
    與partition類似,不過不保證保留容器中的相對順序。 <三>刪除和替換算法(15個) copy:
    複製序列 copy_backward: 與copy相同,不過元素是以相反順序被拷貝。 iter_swap:
    交換兩個ForwardIterator的值。

刪除修改複製(12個):簡單操作區間元素

  1. remove:

    刪除指定範圍內所有等於指定元素的元素。注意,該函數不是真正刪除函數。內置函數不適合使用remove和 remove_if函數。

  2. remove_copy:
    將所有不匹配元素複製到一個制定容器,返回OutputIterator指向被拷貝的末元素的下一個位置。

  3. remove_if:

    刪除指定範圍內輸入操作結果爲true的所有元素。

  4. remove_copy_if:

    將所有不匹配元素拷貝到一個指定容器。

  5. replace:

    將指定範圍內所有等於vold的元素都用vnew代替。

  6. replace_copy:

    與replace類似,不過將結果寫入另一個容器。

  7. replace_if:

    將指定範圍內所有操作結果爲true的元素用新值代替。

  8. replace_copy_if:

    與replace_if,不過將結果寫入另一個容器。

  9. swap:

    交換存儲在兩個對象中的值。

  10. swap_range:

    將指定範圍內的元素與另一個序列元素值進行交換。

  11. unique: (常用於離散化)

    清除序列中重複元素,和remove類似,它也不能真正刪除元素。重載版本使用自定義比較操作。

  12. unique_copy: (同上)

    與unique類似,不過把結果輸出到另一個容器。

排列組合算法(2個):提供計算給定集合按一定順序的所有可能排列組合

以深搜的形式實現:

  1. next_permutation:

    取出當前範圍內的排列,並重新排序爲下一個排列。重載版本使用自定義的比較操作。

  2. prev_permutation:

    取出指定範圍內的序列並將它重新排序爲上一個序列。如果不存在上一個序列則返回false。重載版本使用 自定義的比較操作。

    //常以此方式使用,但時間複雜度N!這個。。。。
    do
    {
    	//操作
    }while((next_permutation(首地址,第一個不合法地址)
    

生成和異變算法(3個)

  1. fill:
    將輸入值賦給標誌範圍內的所有元素。

    fill(首地址,第一個不合法地址,2); //該區間內全部賦值爲2
    

    區別於memset,memset是按位賦值,只能賦每位值相同值。

    memset(首地址,value,(字節數)常用sizeof()獲取)
    
  2. fill_n:

    將輸入值賦給first到first+n範圍內的所有元素。

    // 從開始以此賦值,3個5
    fill_n(首地址,3,5);
    
  3. transform:

    將輸入的操作作用與指定範圍內的每個元素,併產生一個新的序列。重載版本將操作作用在一對元素上,另外一個元素來自輸入的另外一個序列。結果輸出到指定容器。

transform (原始對象首地址, 原始對象第一個不合法地址, 輸出對象首地址, operate(操作函數);
    char operate(char c)//常用轉化大小寫,以此爲例子
    {
    	if (isupper(c))
		{
			return c+32;
		}
		return c;
    }
    

關係算法(6個)

  1. equal:

    如果兩個序列在標誌範圍內元素都相等,返回true。重載版本使用輸入的操作符代替默認的等於操作符。

  2. includes:

    判斷第一個指定範圍內的所有元素是否都被第二個範圍包含,使用底層元素的<操作符,成功返回true。重載版本使用用戶輸入的函數。

  3. max:(很多人問我,這不是cmath嗎,呃。。。。。不是)
    返回兩個元素中較大一個。重載版本使用自定義比較操作。

    max(3,5)的值是5;
    
  4. max_element:

    返回一個ForwardIterator,指出序列中最大的元素。重載版本使用自定義比較操作。

    max_element(a, a+6)  返回一個最大值位置指針
    
  5. min:

    返回兩個元素中較小一個。重載版本使用自定義比較操作。

    min(3,5)的值是5;
    
  6. min_element:

    返回一個ForwardIterator,指出序列中最小的元素。重載版本使用自定義比較操作。

集合算法(4個)

  1. set_union:
    構造一個有序序列,包含兩個序列中所有的不重複元素。重載版本使用自定義的比較操作。

  2. set_intersection:
    構造一個有序序列,其中元素在兩個序列中都存在。重載版本使用自定義的比較操作。

  3. set_difference:
    構造一個有序序列,該序列僅保留第一個序列中存在的而第二個中不存在的元素。重載版本使用自定義的比較操作。

  4. set_symmetric_difference:

構造一個有序序列,該序列取兩個序列的對稱差集(並集-交集)。

堆算法(4個)

  1. make_heap:

    把指定範圍內的元素生成一個堆。重載版本使用自定義比較操作。
    
  2. pop_heap:

    並不真正把最大元素從堆中彈出,而是重新排序堆。它把first和last-1交換,然後重新生成一個堆。可使用容器的back來訪問被"彈出"的元素或者使用pop_back進行真正的刪除。重載版本使用自定義的比較操作。

  3. push_heap:

    假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向該函數前,必須先把元素插入容器後。重載版本使用指定的比較操作。

  4. sort_heap:

    對指定範圍內的序列重新排序,它假設該序列是個有序堆。重載版本使用自定義比較操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章