1. 程式人生 > >c++ STL模板(一)

c++ STL模板(一)

一.sort函式

1、標頭檔案:#include < algorithm>;

2、它使用的排序方法是類似於快排的方法,時間複雜度為n*log2(n);

3、Sort函式有三個引數:(第三個引數可不寫)

(1)第一個是要排序的陣列的起始地址。

(2)第二個是結束的地址(最後一位要排序的地址的下一位地址)。

(3)第三個引數是排序的方法,可以是從大到小也可是從小到大,還可以不寫第三個引數,此時預設的排序方法是從小到大排序。升序:sort(begin,end,less<data-type>());降序:sort(begin,end,greater<data-type>())。

二.lower_bound函式

標頭檔案: #include<algorithm>

函式模板: 如 binary_search()

函式功能:  函式lower_bound()在first和last中的前閉後開區間進行二分查詢,返回大於或等於val的第一個元素位置。如果所有元素都小於val,則返回last的位置,且last的位置是越界的!!

返回查詢元素的第一個可安插位置,也就是“元素值>=查詢值”的第一個元素的位置

三.upper_bound函式

標頭檔案:#include<algorithm>

函式模板: 如binary_search()

函式功能:函式upper_bound()返回的在前閉後開區間查詢的關鍵字的上界,返回大於val的第一個元素位置。

同樣,如果插入元素大於陣列中全部元素,返回的是last。(注意:陣列下標越界)

返回查詢元素的最後一個可安插位置,也就是“元素值>查詢值”的第一個元素的位置。

四.不定長陣列:vector

標頭檔案:#include<vector>

函式功能:vector就是一個不定長陣列。不僅如此,它把一些常用的操作封裝在了vector型別內部。例如,若a是一個vector,可以用a.size()讀取它的大小,a.resize()改變大小,a.push_back()向尾部新增元素,a.pop_back()刪除最後一個元素,a.empty()測試是否為空。

vector是一個模板類,所以需要用vector<int> a或者vector<double> b這樣的方式來宣告一個vector。vector<int>是一個類似於int a[]的整型陣列。vector看上去像“一等公民”,因為他們可以直接賦值,還可以作為函式的引數或返回值,而無須像傳遞陣列那樣另外用一個變數指定元素個數。

五.集合:set

標頭檔案:#include<set>

函式功能:set就是數學上的集合——每個元素最多隻出現一次。和sort一樣,自定義型別也可以構造set,但同樣必須定義“小於”運算子。set<string> dict用來定義一個string集合,dict.insert(buf)用來插入一個字串(由於string已經定義了“小於”運算子,直接使用set儲存字串集合即可)由於set中元素會按從小到大排序這一性質,則set中的字串會按從小到大排好序。

六.對映:map

標頭檔案:#include<map>

函式功能:map就是從鍵(key)到值(value)的對映。因為過載了[ ]運算子,map像陣列的“高階版”。例如可以用一個map<string,int>month_name來表示“月份名字到月份編號”的對映,然後用month_name["July"]=7這樣的方式來賦值。

為了使用方便,可以對模板類進行一下型別定義,

typedef map<int,CString> UDT_MAP_INT_CSTRING;

UDT_MAP_INT_CSTRING enumMap;

        自動建立Key - value的對應。key 和 value可以是任意你需要的型別。

根據key值快速查詢記錄,查詢的複雜度基本是Log(N),如果有1000個記錄,最多查詢10次,1,000,000個記錄,最多查詢20次。

快速插入Key -Value 記錄,insert()函式。

獲取map的大小,size()函式。

快速刪除記錄

根據Key 修改value記錄。

        用count函式來判定關鍵字是否出現,其缺點是無法定位資料出現位置,由於map的特性,一對一的對映關係,就決定了count函式的返回值只有兩個,要麼是0,要麼是1,出現的情況,當然是返回1了。

        用find函式來定位資料出現位置,它返回的一個迭代器,當資料出現時,它返回資料所在位置的迭代器,如果map中沒有要查詢的資料,它返回的迭代器等於end函式返回的迭代器。

查詢map中是否包含某個關鍵字條目用find()方法,傳入的引數是要查詢的key,在這裡需要提到的是begin()和end()兩個成員,

分別代表map物件中第一個條目和最後一個條目,這兩個資料的型別是iterator.

        移除某個map中某個條目用erase(),該成員方法的定義如下:

iterator erase(iterator it);//通過一個條目物件刪除

iterator erase(iterator first,iterator last)//刪除一個範圍

size_type erase(const Key&key);//通過關鍵字刪除

        map中的元素是自動按Key升序排序,所以不能對map用sort函式;這裡要講的是一點比較高深的用法了,排序問題,STL中預設是採用小於號來排序的,以上程式碼在排序上是不存在任何問題的,因為上面的關鍵字是int 型,它本身支援小於號運算,在一些特殊情況,比如關鍵字是一個結構體,涉及到排序就會出現問題,因為它沒有小於號操作,insert等函式在編譯的時候過 不去,所以需要定義一個“小於”運算子“。

        還要說明的是,map中由於它內部有序,由紅黑樹保證,因此很多函式執行的時間複雜度都是log2N的,如果用map函式可以實現的功能,而STL Algorithm也可以完成該功能,建議用map自帶函式,效率高一些。

        下面說下,map在空間上的特性,否則,估計你用起來會有時候表現的比較鬱悶,由於map的每個資料對應紅黑樹上的一個節點,這個節點在不儲存你的 資料時,是佔用16個位元組的,一個父節點指標,左右孩子指標,還有一個列舉值(標示紅黑的,相當於平衡二叉樹中的平衡因子),我想大家應該知道,這些地方 很費記憶體了吧,不說了……

      map的基本操作函式:

     C++ maps是一種關聯式容器,包含“關鍵字/值”對

     begin()         返回指向map頭部的迭代器

     clear()        刪除所有元素

     count()         返回指定元素出現的次數

     empty()         如果map為空則返回true

     end()           返回指向map末尾的迭代器

     equal_range()   返回特殊條目的迭代器對

     erase()         刪除一個元素

     find()          查詢一個元素

     get_allocator() 返回map的配置器

     insert()        插入元素

     key_comp()      返回比較元素key的函式

     lower_bound()   返回鍵值>=給定元素的第一個位置

     max_size()      返回可以容納的最大元素個數

     rbegin()        返回一個指向map尾部的逆向迭代器

     rend()          返回一個指向map頭部的逆向迭代器

     size()          返回map中元素的個數

     swap()           交換兩個map

     upper_bound()    返回鍵值>給定元素的第一個位置

     value_comp()     返回比較元素value的函式

七.棧、佇列與優先佇列

1.棧:標頭檔案:<stack>; 

           用stack<int> s 方式宣告一個棧;

            用push(),pop()實現元素的入棧,出棧操作,top()取棧頂元素(但不刪除)。

2.佇列:標頭檔案:<queue>;

               用queue<int> s 方式宣告一個佇列;

               用push(),pop()實現元素的入隊和出隊操作,front()取隊首元素(但不刪除)。

3.優先佇列:是一種抽象資料型別(Abstract Data Type,ADT),行為類似佇列,但先出的元素不是先進的元素,而是佇列中優先    級最高的元素。

                         標頭檔案:<queue>;

                         用priority_queue<int> qp  來宣告,這個pq是一個“越小的整數優先順序越低的優先佇列”;

                         用push(),pop()實現元素的入隊,出隊操作,top()取隊首元素(但不刪除)。

             自定義型別也可以組成優先佇列,但必須為每個元素定義一個優先順序。這個優先順序並不需要一個確定的數字,只需要能比較大小即可。只要元素定義了“小於”運算子,就可以使用優先佇列。對於一些常見的優先佇列,STL提供了更為簡單的定義方法,例如,“越小的整數優先順序越大的優先佇列”可以寫為"priority_queue<int,vector<int>,greater<int> >pq"。Attention:最後兩個“>"不要寫在一起,否則會被很多(但不是所有)編譯器誤認為是">>"運算子。