STL基礎學習(STL中的容器解析、代碼展現、例題分析,幫助你學STL)

STL就是Standard Template Library(C++標準模板庫),下面是關於STL中的各類內容ios

STL中的幾個基本概念:
算法

1.容器:可容納各類數據類型的數據結構。數組

能夠用於存放各類類型的數據(基本類型的變量,對象等)的數據結構。
容器分爲三大類:
(1) 順序容器  
vector:後部插入/刪除,直接訪問 deque:前/後部插入/刪除,直接訪問 list:雙向鏈表,任意位置插入/刪除數據結構

1) vector  頭文件 <vector>
    實際上就是個動態數組。隨機存取任何元素都能在常數時間完成。在尾端增刪元素具備較佳的性能。
 2) deque   頭文件 <deque>
    也是個動態數組,隨機存取任何元素都能在常數時間完成(但性能次於vector)。在兩端增刪元素具備較佳的性能。
 3) list    頭文件 <list> 
    雙向鏈表,在任何位置增刪元素都能在常數時間完成。不支持隨機存取。
   上述三種容器稱爲順序容器,是由於元素的插入位置同元素的值無關。
( 2)關聯容器
set:快速查找,無重複元素 multiset :快速查找,可有重複元素 map:一對一映射,無重複元素,基於關鍵字查找 multimap :一對一映射,可有重複元素,基於關鍵字查找,前2者合稱爲第一類容器 less

關聯式容器內的元素是排序的,插入任何元素,都按相應的排序準則來肯定其位置。關聯式容器的特色是在查找時具備很是好的性能。
1) set/multiset:   頭文件 <set>
   set 即集合。set中不容許相同元素,multiset中容許存在相同的元素。
2) map/multimap:   頭文件 <map>
   map與set的不一樣在於map中存放的是成對的key/value。
   並根據key對元素進行排序,可快速地根據key來檢索元素
   map同multimap的不一樣在因而否容許多個元素有相同的key值。
   上述4種容器一般以平衡二叉樹方式實現,插入和檢索的時間都是 O(logN)
(3)容器適配器
stack:LIFO queue:FIFO priority_queue:優先級高的元素先出 dom

對象被插入容器中時,被插入的是對象的一個複製品。
許多算法,好比排序,查找,要求對容器中的元素進行比較,因此,放入容器的對象所屬的類,還應該實現 == 和 < 運算符。
1) stack  :頭文件 <stack>
棧。是項的有限序列,並知足序列中被刪除、檢索和修改的項只能是最近插入序列的項。即按照後進先出的原則
2) queue :頭文件 <queue>
   隊列。插入只能夠在尾部進行,刪除、檢索和修改只容許從頭部進行。按照先進先出的原則。
3)priority_queue :頭文件 <queue>
優先級隊列。最高優先級元素老是第一個出列
函數

全部標準庫容器共有的成員函數:
至關於按詞典順序比較兩個容器大小的運算符:   =, < , <= , >  , >=, == , !=
empty : 判斷容器中是否有元素
max_size: 容器中最多能裝多少元素
size:   容器中元素個數
swap: 交換兩個容器的內容
只在第一類容器中的函數:
begin  返回指向容器中第一個元素的迭代器
end     返回指向容器中最後一個元素後面的位置的迭代器
rbegin  返回指向容器中最後一個元素的迭代器
rend    返回指向容器中第一個元素前面的位置的迭代器
erase   從容器中刪除一個或幾個元素
clear   從容器中刪除全部元素

性能

2.迭代器:可依次存取容器中元素的東西spa

用於指向第一類容器中的元素。有const 和非 const兩種。
經過迭代器能夠讀取它指向的元素,經過非const迭代器還能修改其指向的元素。迭代器用法和指針相似。
定義一個容器類的迭代器的方法能夠是:
容器類名::iterator   變量名;
或:
容器類名::const_iterator 變量名;
訪問一個迭代器指向的元素:
* 迭代器變量名
迭代器上能夠執行 ++ 操做, 以指向容器中的下一個元素。若是迭代器到達了容器中的最後一個元素的後面,則迭代器變成past-the-end值。
使用一個past-the-end值的迭代器來訪問對象是非法的,就好像使用NULL或未初始化的指針同樣。指針

算法:用來操做容器中的元素的函數模板。例如,STL用sort()來對一個vector中的數據進行排序,用find()來搜索一個list中的對象。
函數自己與他們操做的數據的結構和類型無關,所以他們能夠在從簡單數組到高度複雜容器的任何數據結構上使用。
好比,數組int array[100]就是個容器,而 int * 類型的指針變量就能夠做爲迭代器,能夠爲這個容器編寫一個排序的算法,如下是各類算法:

#include <vector>
#include <iostream>
using namespace std;
int main()  {
vector<int> v; //一個存放int元素的向量,一開始裏面沒有元素
v.push_back(1);
v.push_back(2); 
v.push_back(3);  
v.push_back(4);
vector<int>::const_iterator i;   //常量迭代器
for( i = v.begin();i != v.end();i ++ ) 
cout << * i << ",";
cout << endl;

vector<int>::reverse_iterator r;  //反向迭代器
for( r = v.rbegin();r != v.rend();r++ ) 
cout << * r << ",";
cout << endl;
vector<int>::iterator j;   //很是量迭代器
for( j = v.begin();j != v.end();j ++ ) 
* j =  100;
for( i = v.begin();i != v.end();i++ ) 
cout << * i << ",";
}
輸出結果:
1,2,3,4,
4,3,2,1,
100,100,100,100,

STL 中的迭代器按功能由弱到強分爲5種:
   1. 輸入:Input iterators 提供對數據的只讀訪問。
   1. 輸出:Output iterators 提供對數據的只寫訪問
   2. 正向:Forward iterators 提供讀寫操做,並能一次一個地向前推動迭代器。
   3. 雙向:Bidirectional iterators提供讀寫操做,並能一次一個地向前和向後移動。
   4. 隨機訪問:Random access iterators提供讀寫操做,並能在數據中隨機移動。
編號大的迭代器擁有編號小的迭代器的全部功能,能看成編號小的迭代器使用。

不一樣迭代器所能進行的操做(功能):

全部迭代器: ++p, p ++
輸入迭代器: * p, p = p1, p == p1 , p!= p1
輸出迭代器: * p, p = p1
正向迭代器: 上面所有
雙向迭代器: 上面所有,--p, p --,
隨機訪問迭代器: 上面所有,以及:
p+= i, p -= i, 
p + i: 返回指向 p 後面的第i個元素的迭代器
p - i: 返回指向 p 前面的第i個元素的迭代器
p[i]:  p 後面的第i個元素的引用
p < p1, p <= p1, p > p1, p>= p1
容器所支持的迭代器類別:

容器 迭代器類別
vector 隨機
deque 隨機
list  雙向
set/multiset 雙向
map/multimap 雙向
stack 不支持迭代器
queue 不支持迭代器
priority_queue 不支持迭代器
例如,vector的迭代器是隨機迭代器,因此遍歷 vector 能夠有如下幾種作法:
vector<int> v(100);
vector<int>::value_type i; //等效於寫 int i;(P687)
for(i = 0;i < v.size() ; i ++)
cout << v[i];
vector<int>::const_iterator ii;
for( ii = v.begin(); ii != v.end ();ii ++ )
cout << * ii;
//間隔一個輸出:
ii = v.begin();
while( ii < v.end()) {
cout << * ii;  
ii = ii + 2; 
}

而 list 的迭代器是雙向迭代器,因此如下代碼能夠:
list<int> v;
list<int>::const_iterator ii;
for( ii = v.begin(); ii != v.end ();ii ++ )
cout << * ii;
如下代碼則不行:
for( ii = v.begin(); ii < v.end ();ii ++ )
cout << * ii;
//雙向迭代器不支持 <
for(int i = 0;i < v.size() ; i ++)
cout << v[i]; //雙向迭代器不支持 []
例子:

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
main()  {
int array[10] = {10,20,30,40};
vector<int> v;
v.push_back(1); v.push_back(2);
v.push_back(3); v.push_back(4);
vector<int>::iterator p;
p = find(v.begin(),v.end(),3);
if( p != v.end())
cout << * p << endl;
p = find(v.begin(),v.end(),9);
if( p == v.end())
cout << "not found " << endl;
p = find(v.begin()+1,v.end()-2,1);
if( p != v.end())
cout << * p << endl;
int * pp = find( array,array+4,20);
cout << * pp << endl;
}
輸出:
3
not found
3
20


例:
int main()  { int i;
int a[5] = {1,2,3,4,5 };    vector<int>  v(5);
cout << v.end()  - v.begin() << endl;
for( i = 0;i < v.size();i ++ )  v[i] = i;
v.at(4) = 100;
for( i = 0;i < v.size();i ++ )
cout << v[i] << "," ;
cout << endl;
vector<int> v2(a,a+5);  //構造函數
v2.insert( v2.begin() + 2, 13 ); //在begin()+2位置插入 13
for( i = 0;i < v2.size();i ++ )
cout << v2[i] << "," ;    
            return 0;
}

輸出:


5
0,1,2,3,100,
1,2,13,3,4,5,


例:
int main()  {
const int SIZE = 5;
int a[SIZE] = {1,2,3,4,5 }; 
vector<int> v (a,a+5);  //構造函數
try {
v.at(100) = 7;
}
catch( out_of_range e) {
cout << e.what() << endl;
}
cout << v.front() << 「,」 << v.back() << endl;
v.erase(v.begin());
ostream_iterator<int> output(cout ,「*");
copy (v.begin(),v.end(),output);
v.erase( v.begin(),v.end());  //等效於 v.clear();


if( v.empty ())
cout << "empty" << endl;
v.insert (v.begin(),a,a+SIZE);
copy (v.begin(),v.end(),output);
}  


// 輸出:
invalid vector<T> subscript
1,5
2*3*4*5*empty
1*2*3*4*5*

關於 ostream_iterator, istream_iterator的例子
int main()  {
istream_iterator<int> inputInt(cin);
int n1,n2;
n1 = * inputInt; //讀入 n1
inputInt ++;   
n2 = * inputInt; //讀入 n2
cout << n1 << "," << n2 << endl;
ostream_iterator<int>> outputInt(cout);
* outputInt = n1 + n2;  cout << endl;
int a[5] = { 1,2,3,4,5};
copy(a,a+5,outputInt);  //輸出整個數組
            return 0;
}

程序運行後輸入 78  90敲回車,則輸出結果爲:
78,90
168
12345


例';

#include <set>
#include <iostream>
using namespace std;
int main()  {
typedef set<double,less<double> > double_set;
const int SIZE = 5;
double a[SIZE] = {2.1,4.2,9.5,2.1,3.7 };
double_set doubleSet(a,a+SIZE);
ostream_iterator<double> output(cout," ");
cout << "1) ";
copy(doubleSet.begin(),doubleSet.end(),output);
cout << endl;
      pair<double_set::const_iterator, bool> p;
      p = doubleSet.insert(9.5); 
      if( p.second ) 
cout << "2) " << * (p.first)  << " inserted" << endl;
      else
            cout << "2) " << * (p.first)  << " not inserted" << endl;
      return 0; }



輸出:
1) 2.1 3.7 4.2 9.5
2) 9.5 not inserted


#include <iostream>
#include <map>
using namespace std;
ostream & operator <<( ostream & o,const pair<  int,double> & p)
{
o << "(" << p.first  << "," << p.second << ")";
return o;
}
int main()  {
typedef map<int,double,less<int> > mmid;
mmid pairs;
cout << "1) " << pairs.count(15) << endl;
pairs.insert(mmid::value_type(15,2.7));
pairs.insert(make_pair(15,99.3));//make_pair生成pair對象
cout << "2) " << pairs.count(15) << endl;
pairs.insert(mmid::value_type(20,9.3));

      mmid::iterator i;
      cout << "3) ";
      for( i = pairs.begin(); i != pairs.end();i ++ )
    cout << * i  << ",";
cout << endl;
cout << "4) ";
int n =  pairs[40];//若是沒有關鍵字爲40的元素,則插入一個
for( i = pairs.begin(); i != pairs.end();i ++ )
cout << * i  << ",";
cout << endl;
cout << "5) ";
pairs[15] = 6.28; //把關鍵字爲15的元素值改爲6.28
for( i = pairs.begin(); i != pairs.end();i ++ )
cout << * i  << ",";
            return 0;
}



輸出:
1) 0
2) 1
3) (15,2.7),(20,9.3),
4) (15,2.7),(20,9.3),(40,0),
5) (15,6.28),(20,9.3),(40,0),


如何用程序用來統計一篇英文文章中單詞出現的頻率(爲簡單起見,假定依次從鍵盤輸入該文章) 
       #include <iostream

> #include <map>

using namespace std;

int main() {  

  map<string, int> wordCount;   

 string word;    

while (cin >> word)        

++wordCount[word];       

 for (map<string, int>::iterator it = wordCount.begin(); it !=    wordCount.end(); ++it)  

     cout<<"Word: "<<(*it).first<<" \tCount: "<<(*it).second<<endl;      

  return 0; }



例:

#include <queue>
#include <iostream>
using namespace std;
int main()  {
priority_queue<double> priorities;
priorities.push(3.2);
priorities.push(9.8);
priorities.push(5.4);
while( !priorities.empty() ) {
cout << priorities.top() << " ";    priorities.pop();
}
     return 0;

//輸出結果:9.8 5.4 3.2


例:

int main()  {
const int SIZE = 10;
int a1[] = { 2,8,1,50,3,100,8,9,10,2 };
vector<int> v(a1,a1+SIZE);
ostream_iterator<int> output(cout," ");
vector<int>::iterator location;
location = find(v.begin(),v.end(),10);
if( location != v.end()) {
cout << endl << "1) " << location - v.begin();
}
  sort(v.begin(),v.end());
       if( binary_search(v.begin(),v.end(),9)) 
           cout << endl << "3) " << "9 found";
      else
    cout << endl << " 3) " << " 9 not found";       
      return 0;
}

輸出:(無sort語句)


1) 8
2) 3
3) 9 not found

輸出: (有sort語句) 1) 8 2) 3 3) 9 found

相關文章
相關標籤/搜索