1.容器
1.1 stack
stack是一種先進后出的數據結構酿雪,stack 模板類的定義在<stack>頭文件中。
stack 模板類需要兩個模板參數瘪撇,一個是元素類型,一個容器類型堡赔,但只有元素類型是必要
的,在不指定容器類型時设联,默認的容器類型為deque善已。
定義stack 對象的示例代碼如下:
stack<int> s1;
stack<string> s2;
stack 的基本操作有:
入棧灼捂,如例:s.push(x);
出棧,如例:s.pop();注意换团,出棧操作只是刪除棧頂元素悉稠,并不返回該元素。
訪問棧頂艘包,如例:s.top()
判斷椀拿停空,如例:s.empty()想虎,當椮宰穑空時,返回true舌厨。
訪問棧中的元素個數岂却,如例:s.size()。
補充:stack的三種含義
含義一:數據結構
stack的第一種含義是一組數據的存放方式裙椭,特點為LIFO躏哩,即后進先出(Last in, first out)。
既上述stl中所描述的stack
含義二:代碼運行方式
stack的第二種含義是"調用棧"(call stack)揉燃,表示函數或子例程像堆積木一樣存放扫尺,以實現層層調用。
含義三:內存區(qū)域
stack的第三種含義是存放數據的一種內存區(qū)域炊汤。程序運行的時候器联,需要內存空間存放數據。一般來說婿崭,系統(tǒng)會劃分出兩種不同的內存空間:一種叫做stack(棧)拨拓,另一種叫做heap(堆)。
它們的主要區(qū)別是:stack是有結構的氓栈,每個區(qū)塊按照一定次序存放渣磷,可以明確知道每個區(qū)塊的大小授瘦;heap是沒有結構的醋界,數據可以任意存放。因此提完,stack的尋址速度要快于heap形纺。
2.2 queue
queue 隊列也是一個線性存儲表,與后進先出的堆棧不同徒欣,元素數據的插入在表的一端進行逐样,在另一端刪除,從而構成了一個先進先出(First In First Out) 表。插入一端稱為隊尾脂新,刪除一端稱為隊首挪捕。
由于C++ STL 的隊列泛化,默認使用雙端隊列 deque 來實現争便,因此级零,queue 也可看成一個容器的適配器,將 deque 容器轉換為 queue 容器滞乙。當然奏纪,也可以利用其它合適的序列容器作為底層實現 queue 容器。
queue隊列容器的C++標準頭文件為 queue 斩启,需要用宏語句 "#include <queue>" 包含進來才可應用 queue 容器進行開發(fā)序调。
1.3 map
map是一種關聯容器,存儲的對象是一組key/value
不允許有重復的key
map存儲的對象必須是可排序性的
template<class _kty, class _ty, class _pr = less<_kty>,
class _Alloc = allocator<pari<const _kty,_ty>>>
class map{...}
默認采用less定義排序行為浇垦,如果map中存儲的是自己定義的類炕置,則需要重載operator <
或者可以通過仿函數自定義排序行為
1.3 set
set是一種關聯容器,存儲的對象既是key又是value
這是 set與map的最大區(qū)別
MAP的節(jié)點是一對數據.
SET的節(jié)點是一個數據.
Map使用關鍵值Key來唯一標識每一個成員 男韧,map可以重復朴摊。
set是集合 ,不能重復
在作業(yè)中遇到的問題:set的iterator類型自動就是const的引用類型此虑,因此當set保存的是類類型時甚纲,對iterator解引用無法調用類的非const成員。
解決辦法:1.set中不存儲對象本身朦前,改為存儲對象指針
2.利用const_cast<Programmer&> 進行轉型
2.仿函數
仿函數又稱函數對象介杆,從名字上可以得出,它本質上是 **一種具有函數特質的對象**韭寸, 也即可以像使用函
數一樣使用該對象春哨。怎么樣做?重載operator()運算符即可恩伺,有了這個運算符赴背,我們就可以在仿函數對象后
面加上一對小括號,以此調用仿函數所定義的operator()晶渠。STL仿函數可以分為一元和二元凰荚,或者算術運
算、關系運算和邏輯運算褒脯。
為什么要有仿函數便瑟?在算法的設計過程中,我們會發(fā)現其本質往往是不變的(例如排序算法的思想)番川,變
化的除了數據之外還有操作(例如排序中不一定是比較大小到涂,也可以是兩兩之間滿足某種關系)脊框,仿函數就
是為了這種情況產生的,它替代原來需要函數指針的地方养盗,把這種操作或者策略傳給算法缚陷,使得算法抽象性
更高适篙,也就更通用往核。
為什么不用函數指針?很簡單的解釋是抽象性不夠嚷节,更進一步說是它無法配接聂儒,也就是可以將操作配接在
一起變換為更復雜的操作(例如compose和bind1st等等方法),仿函數則可以輕松實現這些配接硫痰,使得其功
能異常強大衩婚。
仿函數在實現上是一個結構體,并且如上所述重載了operator()運算符效斑,所有的仿函數如果是一元的都繼
承自unary_function非春,二元則繼承自binary_function,因為繼承自這兩個函數的仿函數均定義了相應型別供
配接時使用,也就具有了配接能力缓屠。
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
2.仿函數適配器
由于在for_each的定義中只接受f(obj)這種類型的調用奇昙,mem_fun和mem_fun_ref的存在可以讓obj的成員函數f可以以f(obj)這種形式被調用
for_each(set1.begin() , set1.end() , mem_fun(&Programmer::print));
需要注意的是如果set中存儲的是對象本身,則需要使用mem_fun_ref,如果存儲的是對象指針則使用mem_fun