1. 程式人生 > >C++ STL的使用方法(轉)

C++ STL的使用方法(轉)

1.概述泛型程式設計思想最早緣於A.Stepanov提出的部分演算法可獨立於資料結構的論斷。20世紀90年代初A.Stepanov和Meng Lee根據泛型程式設計的理論用C++共同編寫了STL。但直至1998年,STL才成為C++的正式標準。在後來的幾年中,各大主流編譯器也都相繼加入了對STL的支援,至此STL才開始得到廣泛的應用。STL體現的是泛型程式設計的核心思想:獨立資料結構和演算法(這是一種獨立於OO的程式設計哲學)。STL主要由幾個核心部件組成,即迭代器、容器、演算法、函式物件、介面卡。容器即物之所屬;演算法是解決問題的方式;迭代器是對容器的訪問邏輯的抽象,是連線演算法和容器的紐帶;迭代器通過添加了一種間接層的方式實現了容器和演算法之間的獨立;函式物件,就是過載了operator()操作符的物件;介面卡是通過組合特定的容器實現的一種新的資料結構。在後續的內容中,我們將對幾個核心部件的基礎應用進行詳細的描述。2.
基礎
C++產生的歷史背景賦予了C++太多的職責,比如相容C、綜合的程式語言等,這些雖然賦予了C++強大的功能,但同時也扔給了極大的複雜度。在這篇文章中,我們並不打算將你帶入C++的複雜地帶,但是需要你有一定的C++基礎,比如類、結構等。STL深深地植根於C++的基礎設施,這其中包括了內聯、函式物件、函式模板、類模板等。內聯是C++中一種特殊的語言機制,使用inline來標識。C++在編譯inline標識的函式時,將根據特定的規則將inline函式的程式碼直接插入到inline函式的呼叫位置,以此來提高程式的執行效率,但同時也在一定程度上導致了程式碼的膨脹。請看下面的例子:inline全域性函式
inline void max{…};inline成員函式class A{public:         inline void max{…};}函式物件,就是過載了operator()操作符的物件。相對函式指標,函式物件可以具有狀態,更安全,更靈活,基本沒有額外的開銷。在STL中,函式物件經常被用作演算法的輸入引數或容器的例項化的引數。請看下面的例子:定義函式物件類classs LessThan{public:         LessThan(int val): m_val(val){}         bool operator()(int val){return m_val < val;}
private:         int m_val;};定義函式物件LessThan less(5);呼叫定義函式物件less(10);//返回為trueC++中的模板是STL實現的技術基礎。C++中的模板可分為函式模板和類模板。函式模板抽象了針對不同型別的同一性質的操作。如針對int/long/string的max操作。請看下面的例子:定義求取兩個型別的值或物件的最大值的操作template<typename T>T max(T a,T b){return a>b ? a : b;}求取兩個int值的最大值max(0,10);//返回10求取兩個string物件的最大值max(string(“Hello”),string(“world”));//返回string(“world”)C++中的模板是STL實現的技術基礎。C++中的模板可分為函式模板和類模板。類模板抽象了針對不同型別的同一類事務。如針對int/long/string的Stack。請看下面的例子:定義一個通用堆疊Stacktemplate<typename T>class Stack{public:         inline void push(const T& value){…}         T pop(){…}void clear(){…}bool empty() const {…}};宣告一個int型別的Stacktypdef Stack<int> IntStack;宣告一個string型別的Stacktypdef Stack<string> IntStack;3.迭代器STL中的迭代器是C++指標的泛化,它在演算法和容器之間充當一箇中間層,為處理不同的資料結構提供了一致的方式。迭代器也可以看作是對容器資料結構訪問的一種約束。STL中的迭代器可分為類:隨機存取迭代器(random-access-iterator),雙向存取迭代器(bidirectional-access-iterator),前向迭代器(forward iterator),輸入迭代器(input-iterator),輸出迭代器(output-iterator)。它們之間的繼承關係如下圖: input-iterator output-iteartor      forward-iterator:output-iteartor , input-iterator bidirectional-access-iterator : forward-iteratorrandom-access-iterator:bidirectional-access-iterator圖一 迭代器關係圖輸入迭代器也可以稱之為前向的只讀訪問器,首先它提供了對容器的只讀訪問,其次它只能在容器中進行前向迭代(即只提供++操作)。所有的容器的迭代器都具有輸入迭代器的特徵。通過輸入迭代器你可以進行下面三種操作:1.V = *X++2.V = *X,X++3.V = *X,++X注:V為值,X為迭代器輸出迭代器也可以稱之為前向的只寫訪問器,首先它提供了對容器的只寫訪問,其次它只能在容器中進行前向迭代(即只提供++操作)。通過輸出迭代器你可以進行下面三種操作:1.*X++ = V2.*X = V, X++3.*X = V, ++X注:V為值,X為迭代器前向迭代器繼承自輸入和輸出迭代器,因此具有輸入和輸出迭代器的所有特徵,也即提供對容器資料結構的讀寫訪問但也只具有前向迭代的能力(即只提供++操作)。因此,你可以對前向迭代器進行操作:R == S /++R == ++S。請看下面的例子:定義一個利用前向迭代器進行線性查詢的演算法template<typename ForwardIterator,typename T>ForwardIterator linear_search(ForwardIterator first,ForwardIterator last,const T& value){         for (; first != last; ++first){                   if (*first == value)                            return first;}return last;}測試int ia[] = {35,3,23};vector<int> vec(ia,ia+3);vector<int>::iterator it = linear_search(vec.begin(),vec.end(),100);if (it != vec.end())std::cout << "Found" << endl;elsestd::cout << "Not Found" << endl;測試結果為:Not Found雙向存取迭代器從前向迭代器繼承過來,因而具有前向迭代器的所有特徵,雙向存取迭代器還具有後向訪問能力(即只提供--操作)。請看下面的例子:定義一個利用雙向迭代器排序演算法template<typename BidirectionalIterator,typename Compare>void sort_me(BidirectionalIterator first,BidirectionalIterator last,Compare comp){    for(BidirectionalIterator i = first; i != last; ++i)    {        BidirectionalIterator _last = last;        while(i != _last--)        {            if (comp(*i,*_last))                iter_swap(i,_last);        }    }}測試int ia[] = {123,343,12,100,343,5,5};vector<int> vec(ia,ia+7);sort_me(vec.begin(),vec.end(),less<int>());copy(vec.begin(),vec.end(),ostream_iterator<int>(cout," "));std::cout << endl;測試結果為:5 5 12 100 123 343 343隨機存取迭代器從雙向存取迭代器繼承過來,因而具有雙向存取迭代器的所有特徵。所不同的是,利用隨機存取迭代器你可以對容器資料結構進行隨機訪問,因而隨機存取迭代器還可以定義下面的操作:1.operator+(int)2.operator+=(int)3.operator-(int)4.operator-=(int)5.operator[](int)6.operator-(random-access-iterator)7.operator>(random-access-iterator)8.operator<(random-access-iterator)9.operator>=(random-access-iterator)10.operator<=(random-access-iterator)在STL中,隨機存取雙向迭代器只能作用於順序容器。請看下面的例子:測試輸出vector裡面的資料    int ia[] = {123,343,12,100,343,5,5};    vector<int> vec(ia,ia+7);    for(int i = 0; i < vec.size(); ++i)        std::cout << vec[i] << " ";測試結果為:123 343 12 100 343 5 54.容器容器即物之所在。容器是STL的核心部件之一,是迭代器的依附,是演算法作用的目標。STL中的容器可分為順序容器(Sequence Container)和關聯容器(Associative Container)。容器介面卡(Container Adaptor)是對順序容器(Sequence Container)或關聯容器(Associative Container)進行包裝而得到的一種具有更多約束力(或功能更強大)的容器。下表列出的是STL中的主要(標準和非標準的)容器:
順序容器(Sequence Container)容器備註
vector
stack非STL標準,vector的介面卡(Adaptor)
list
slist非STL標準,list的介面卡(Adaptor)
deque
priority_queue非STL標準,deque的介面卡(Adaptor)
queue非STL標準,deque的介面卡(Adaptor)
關聯容器(Associative Container)set底層資料結構是RB-tree(紅黑樹)
multiset底層資料結構是RB-tree(紅黑樹)
map底層資料結構是RB-tree(紅黑樹)
multimap底層資料結構是RB-tree(紅黑樹)
hashtable非STL標準
hash_set非STL標準,底層資料結構是hashtable
hash_map非STL標準,底層資料結構是hashtable
hash_multiset非STL標準,底層資料結構是hashtable
hash_multimap非STL標準,底層資料結構是hashtable)
所有的容器都是物之所在,這就決定了它們必然存在很多共性,這些共性包括迭代器、大小等屬性。容器與容器之間的主要區別體現在對資料的操作上。每類容器都包含四個迭代器:iterator(正向迭代器)、const_iterator(常正向迭代器)、reverse_iterator(反向迭代器)、const_reverse_iterator(常反向迭代器)。因此你可以按照下面的方式獲取每個容器的相應的迭代器:獲取正向迭代器C<T>::iterator it = c.begin();C <T>::iterator it = c.end();獲取反向迭代器C <T>::reverse_iterator it = c.rbegin();C <T>:: reverse_iterator it = c.rend()獲取常正向迭代器C<T>::const_iterator it = c.begin();C <T>:: const_iterator it = c.end();獲取常反向迭代器C <T>:: const_ reverse_iterator it = c.rbegin();C <T>:: const_ reverse_iterator it = c.rend()注:C為容器型別,cC的例項所有容器是資料的存在之處,可以看作的是資料的集合,因此它們都會有大小、是否為空等屬性,因此你可以按照下面的方式獲取所有的容器的公共屬性:

相關推薦

c++ stl vector陣列(實際是陣列的指標)

轉自:http://www.cnblogs.com/loongfee/archive/2012/05/05/2484574.html   std::vector很方便,但有時呼叫的函式的引數規定是陣列,需要將vector轉為陣列,另外開闢一個空間,將vector一項項複

C++ STL的使用方法()

1.概述泛型程式設計思想最早緣於A.Stepanov提出的部分演算法可獨立於資料結構的論斷。20世紀90年代初A.Stepanov和Meng Lee根據泛型程式設計的理論用C++共同編寫了STL。但直至1998年,STL才成為C++的正式標準。在後來的幾年中,各大主流編譯器也

C# 獲取當前路徑方法()

關聯 direct 引入 安全 判斷 是我 forms 字符串 sof C# 獲取當前路徑方法 //獲取包含清單的已加載文件的路徑或 UNC 位置。 public static string sApplicationPath = Assembly.

Linux下c實現域名IP的方法封裝

rrd dbv mvm com inf adk lan fad bho 蝕古戮一爸下戀墩諂棧鐘啥材諭http://jz.docin.com/kjr58937 囪弛探刻煌俺厴嘲蹤以洶趴敵柿http://www.docin.com/app/user/userinfo?useri

()C++STL中優先隊列的使用

clas pre article return mes 就是 name 結構體 using 原文地址 說到隊列,我們首先想到就是先進先出,後進後出;那麽何為優先隊列呢,在優先隊列中,元素被賦予優先級,當訪問元素時,具有最高級優先級的元素先被訪問。即優先隊列具有最高級先出的

C++STL 中的線性容器整體/逐元素操作方法 少寫80%for循環

個數 multipl 頭文件 turn 含義 enc function thead gcd 本文中示例代碼默認已引用 std 命名空間 累加 (std::accumulate) accumulate(begin, end, init, op) 返回給定區間內元素的累加值與給

C++ STL queue 隊列容器 基本方法

隊列大小 bsp 元素 隊列 c++ queue ont emp 入隊 創建隊列 queue<int> que; 讀取隊首元素 que.front(); 讀取隊尾元素 que.back(); 元素入隊 queue.pust(); 元素出隊 qu

c語言char* char[]方法

vector<char *> splite_by_delim(char* host_name){ char a[1000]; strcpy(a,host_name); char *p = strtok(a , split); vector<char

C++中int LPCWSTR方法,配合MessageBox使用

1.MultiByteToWideChar函式方式 int nctimes; string str; str = std::to_string(nctimes); size_t size = str.length(); wchar_t *buffer

C/C++ 中 int string,string int 的幾種方法

C int 轉 string sprintf int a = 1; char strDst[256] = {0}; sprintf_s(strDst,256,"%d",a); itoa int

()C++ STL中map.erase(it++)用法原理解析

之前在程式碼中使用map::erase函式時,誤搬了vector::erase的用法,導致Server down掉了,好在在測試環境就及時發現了問題,在上線前進行了補救==。  以下總結一下map::erase的正確用法。  首先看一下在迴圈中使用vector::eras

C# 透明窗體制作方法()

有時候自己做一些小工具,希望做一些看起來比較特殊的樣子。 很多時候我們的窗體形狀都是不規則的,或者背景的透明的。那麼我們怎麼在.net中實現這樣的效果呢?   方式一: 其實很簡單,是要設定窗體的邊框樣式為None並且設定透明引數就可以了。 效果圖:   private v

c++ STL 之 unorder_map及unorder_set使用自定義類作為key的方法

  #include <iostream> #include <string> #include <unordered_map> #include <unordered_set> using namespace std; str

c++ STL中sort函式的三種使用方法

複習一下~ STL,C++中的標準模板庫, 使用起來方便並且效率較高; sort函式有三種用法: 一:對基本型別陣列從小到大排序 sort( 陣列名+n1,陣列名+n2); 將陣列中下標從n1到n2的元素進行從小到大排序,不包括n2,通過n1,n2 可以對整

c++STL map用法(

此文章源於博主(sunshinewave),轉到自己部落格以後方便檢視 map是STL的一個關聯容器,它提供一對一(其中第一個可以稱為關鍵字,每個關鍵字只能在map中出現一次,第二個可能稱為該關鍵字的值)的資料處理能力,由於這個特性,它完成有可能在我們處理一對一

C++ STL--stack/queue 的使用方法

1、stack stack 模板類的定義在標頭檔案中。 stack 模板類需要兩個模板引數,一個是元素型別,一個容器型別,但只有元素型別是必要 的,在不指定容器型別時,預設的容器型別為deque。 定義stack 物件的示例程式碼如下: stack s

C++ STL 順序容器訪問最後一個元素的方法

     遇到個需求,需要實現訪問list的最後一個元素,不想通過遍歷獲取(因為list可能很長)。於是尋找如何方便的訪問list的最後一個元素。C++ Primer上面沒有很明確的說明,只是說了迭代器 iterator的操作方法和範圍。範圍是[begin,end),操作有

C++ STL unordered_map介紹與使用方法

unordered_map(無序對映) 對於map,前面已經提到過,其內部資料結構為紅黑樹,因此所有元素插入到map裡面都會排好序,而且搜尋過程為平衡二叉樹搜尋,因此時間複雜度為O(logN)。我們知

C++STL bitset介紹與使用方法

bitset bitset主要是用於儲存二進位制位,在需要大量二進位制計算的專案中,直接使用bitset比利用陣列或者其它方式要更為方便,位運算在儲存狀態、模擬行動、搜尋很多方面有非常巨大的優勢

C++ STL stack介紹與使用方法

stack(棧) 在學習資料結構中我們知道,棧是一種邏輯資料結構,其具有後進先出的特性。同時,我們也可以把它想象成一個容器,一個真實容器,新增與刪除只能在容器頂部完成。棧的應用非常廣,我們知道任何程式從記憶體進入CPU執行,系統為了保證程式正確的執行,將程式二