容器:可容納各類數據類型的通用數據結構,是類模版ios
迭代器:可用於依次存取容器中元素,相似於指針算法
算法:用來操做容器中的元素的函數模版數組
算法自己與他們操做的數據類型無關,所以他們能夠在從簡單數組道高度複雜容器的任何數據結構上使用數據結構
int array[100]; //該數組就是容器,而int* 類型的指針變量就能夠做爲迭代器,sort算法能夠做用於該容器上,對其進行排序 sort(array,array+70);//將前70個元素排序,array和array+70就是兩個迭代器
能夠用於存放各類類型的數據(基本類型的變量、對象等)的數據結構,都是類模版,分爲三種:less
對象被插入容器中時,被插入的是對象的一個複製品。許多算法,好比排序、查找,要求對容器中的元素進行比較,有的容器自己就是排序的,因此,放入容器的對象所屬的類,每每還應該重載==和<運算符數據結構和算法
容器並不是排序的,元素的插入位置同元素的值無關函數
有vector,deque,list三種性能
vector 頭文件<vector>spa
向量,動態數組,元素在內存連續存放,隨機存取任何元素都能在常數時間完成。在尾端增刪元素具備較佳的性能(大部分狀況下是常數時間,由於一般會預留一些存儲空間,因此時間複雜度是常數;偶爾會由於空間不夠而變成o(n) )。設計
duque 頭文件<deque>
雙向隊列,元素在內存連續存放。隨機存取任何元素都能在常數時間完成(但次於vector,由於須要判斷是否越界,是否須要重置到頭部)。在兩端增刪元素具備較佳的性能(大部分狀況下是常數時間,只有在須要從新分配存儲空間的時候纔會變成o(n))
list 頭文件<list>
雙向鏈表。元素在內存不連續存放。在任何位置增刪元素都能在常數時間完成。不支持隨機存取。
元素是排序的
插入任何元素,都按相應的排序規則來肯定其位置
在查找時具備很是好的性能(排序的目的)
一般以平衡二叉樹的方式實現,插入和檢索的時間都是o(log(N))
set/multiset 頭文件<set>
set 即集合。set中不容許相同元素,multiset中容許相同的元素
map/multimap 頭文件<map>
map與set的不一樣在於map中存放的元素有且僅有兩個成員變量,一個名爲first,一個名爲second,map根據first值對元素進行從小到大的排序,並可快速的根據first來檢索元素。
map同multimap的區別在因而否容許相同first值的元素
stack:頭文件<stack>
棧。是項的有限序列,並知足序列中被刪除、檢索和修改的項職能是最近插入序列的項(棧頂的項)。後進先出。
queue 頭文件<queue>
隊列。插入只能夠在尾部進行,刪除、檢索和修改只容許從頭部進行。先進先出
priority_queue 頭文件<queue>
優先級隊列,最高優先級元素老是第一個出列
用於指向順序容器和關聯容器中的元素
迭代器用法和指針相似
有const和非const兩種
經過迭代器能夠讀取它指向的元素
經過非const迭代器還能修改其指向的元素
定義一個容器類的迭代器的方法:
容器類名::iterator/const_iterator 變量名;
訪問一個迭代器指向的元素
* 迭代器變量名
迭代器上能夠執行++操做,從而使其指向容器中的下一個元素。但若是迭代器到達了容器中的最後一個元素的後面,此時再使用它,就會出錯,相似於使用NULL或未初始化的指針同樣。
迭代器類別
遍歷vector(deque)
vector<int> v(100); int i; 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;
遍歷list(所用的是雙向迭代器)
list<int> v; list<int>::const_iterator ii; for(ii = v.begin();ii != v.end(); ++ii) cout << * ii; //錯誤的作法,雙向迭代器不支持<,list沒有[]成員函數 for( ii = v.begin();ii<v.end();ii++) cout << * ii; for(int i = 0; i < v.size();i++) cout << v[i];
算法就是一個個函數模版,大多數在<algorithm>中定義
STL中提供能在各個容器中通用的算法,好比查找,排序等
算法經過迭代器來操縱容器中的元素。許多算法能夠對容器中的一個局部區間進行操做,所以須要兩個參數,一個是起始元素的迭代器,一個是終止元素的後面的一個元素的迭代器。好比,排序和查找。
有的算法返回一個迭代器,好比find()算法,在容器中查找一個元素,並返回一個指向該元素的迭代器
算法能夠處理容器,也能夠處理普通數組
示例:find() 一般用於實現順序查找
template<class Init, class T> Init find(Init first, Init last, const T& val);
關聯容器內部的元素是從小到大排序的
有些算法要求其操做的區間是從小到大排序的,稱爲「有序區間算法」(binary_search)
有些算法會對區間進行從小到大排序,稱爲「排序算法」
還有一些其餘算法會用到「大」,「小」的概念
使用STL時,在缺省的狀況下,如下三個說法等價
可變長的動態數組(相較於靜態數組而言)
必須包含頭文件 #include <vector>
支持隨機訪問迭代器
全部STL算法 都能對vector操做
構造函數初始化
成員函數 | 做用 |
---|---|
vector(); | 無參構造函數,將容器初始化成空的 |
vector(int n); | 將容器初始化成有n個元素 |
vector(int n, const T& val); | 假定元素類型是T,將容器初始化成有n個元素,每一個元素的值都是val |
vector(iterator first, iterator last); | 將容器初始化爲與別的容器上區間爲[first,last)一致的內容 |
其餘經常使用函數
成員函數 | 做用 |
---|---|
void pop_back(); | 刪除容器末尾的元素 |
void push_back(const T & val); | 將val添加到容器末尾 |
int size(); | 返回容器中元素的個數 |
T & front(); | 返回容器中第一個元素的引用 |
T & back(); | 返回容器中最後一個元素的引用 |
//例1 #include <iostream> #include <vector> using namespace std; int main() { int i; int a[5] = {1,2,3,4,5}; vector<int> v(5); cout<<v.end()-v.begin()<<endl;//輸出5 for(i = 0; i < v.size();i++) v[i] = i;//能夠用方括號直接訪問 v.at(4) = 100;//將第5個元素賦值爲100 for(i = 0; i < v.size();i++) cout<< v[i] << ","; // 0,1,2,3,100 cout << endl; vector<int> v2(a,a+5);//構造函數 v2.insert(v2.begin()+2,13);//在begin()+2位置插入13 for(i = 0; i < v2.size();i++)//1,2,13,3,4,5 cout<<v2.at(i)<<","; }
vector< vector<int>> v(3); //v有3個元素 //沒個元素都是vector<int>容器
#include <iostream> #include <vector> using namespace std; int main() { vector<vector<int>> v(3); for(int i=0; i < v.size();++i) for(int j=0; j < 4; ++j) v[i].push_back(j); for(int i = 0; i < v.size();++i) { for(int j = 0; j < v[i].size(); ++j) cout << v[i][j] << " "; cout << endl; } return 0; }
成員函數 | 做用 |
---|---|
push_front | 在鏈表最前面插入 |
pop_front | 刪除鏈表最前面的元素 |
sort | 排序(list不支持STL的算法sort) |
remove | 刪除和指定值相等的全部元素 |
unique | 刪除全部和前一個元素相同的元素 |
merge | 合併兩個鏈表並清空被合併的鏈表 |
reverse | 顛倒鏈表 |
splice | 在指定位置前面插入另外一鏈表中的一個或多個元素,並在另外一鏈表中刪除被插入的元素 |
list<T> classname; classname.sort(compare); //compare函數能夠本身定義 classname.sort(); //無參數版本,按<排序
#include<list> #include<iostream> #include<algorithm> using namespace std; class A { //定義類A,並以友元重載<,==,<< private: int n; public: A( int n_) {n = n_;} friend bool operator< (const A & a1, const A & a2); friend bool operator== (const A & a1, const A & a2); friend ostream & operator << (ostream & o, const A & a); }; bool operator < (const A & a1, const A & a2) { return a1.n < a2.n } bool operator== (const A & a1, const A & a2) { return a1.n == a2.n } ostream & operator << (ostream & o, const A & a) { o << a.n; return o; } //定義函數模版PrintList,打印列表中的對象 template <class T> void PrintList(const list<T> & lst) { int tmp = lst.size(); if( tmp > 0){ typename list<T>::const_iterator i; i = lst.begin(); for(i = lst.begin();i!=lst.end();i++) cout << *i << ","; } } //與其餘順序容器不一樣,list容器只能使用雙向迭代器 //所以不支持大於/小於比較運算符,[]運算符和隨機移動 //typename用來講明 list<T>::const_iterator 是個類型 //在VS中不寫也能夠
class CMyAverage{//函數對象類 public: double operator()(int a1, int a2, int a3) { return (double)(a1+a2+a3)/3; } }; CMyAverage average;//函數對象 cout << average(3,2,3); //average.operator()(3,2,3) //輸出2.66667
//Dev C++中的Accumulate源代碼1 template <typename _InputIterator, typename _Tp> _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { for(;__first != __last; ++__first) __init = __init + *__first; return __init; } //typename 等價於 class //Dev C++中的Accumulate源代碼2 template <typename _InputIterator, typename _Tp,typename _BinaryOperation> _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) { for(;__first != __last; ++__first) __init = __binary_op(__init, *__first); return __init; } //調用accumulate時,和__binary_op對應的實參能夠是一個函數或函數對象
#include <iostream> #include <vector> #include <algorithm> #include <numeric> #include <functional> using namespace std; int sumSquares(int total, int value) { return total + value * value; } template <class T> void PrintInterval(T first, T last) {//輸出區間[first,last)中的元素 for(;first!=last;++first) cout<<*first<<" "; cout<<endl; } template<class T> class SumPowers { private: int power; public: SumPowers(int p):power(p){} const T operator()(const T & total, const T & value) {//計算value的power次方,加到total上 T v = value; for(int i = 0; i < power - 1 ; ++i) v = v * value; return total + v; } }; int main() { const int SIZE = 10; int a1[] = {1,2,3,4,5,6,7,8,9,10}; vector<int> v(a1,a1+SIZE); cout << "1."; PrintInterval(v.begin(),v.end()); int result = accumulate(v.begin(),v.end(),0,SumSquares);//🌟 cout << "2.平方和" << result << endl; result = accumulate(v.begin(),v.end(),0,SumPowers<int>(3));//🌛 cout << "3.立方和" << result << endl; result = accumulate(v.begin(),v.end(),0,SumPowers<int>(4)); cout << "4.四次方和" << result << endl; return 0; } //🌟句實例化出 int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, int(*op)(int,int)) { for(;first != last; ++first) init = op(init, *first); return init; } //🌛句實例化出 int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, SumPowers<int> op) { for(;first != last; ++first) init = op(init, *first); return init; }
如下模版能夠用來生成函數對象
頭文件:<functional>
template <class T> struct greater: public binary function <T, T, bool>{ bool operator()(const T& x, const T& y) const{ return x > y; } };
list有兩個sort成員函數
void sort();
將list中的元素按"<"規定的比較方法升序排列
template <class Compare>
void sort(Compare op);
將list中的元素按op規定的比較方法升序排列,即要比較x,y大小時,看op(x,y)的返回值,爲true則認爲x小於y
#include <list> #include <iostream> using namespace std; class MyLess{ public: bool operator()(const int & c1, const int & c2) { return (c1 % 10) < (c2 % 10); } }; template <class T> void Print(T first, T last) { for(;first != last;++first) cout << * first << ","; } int main() { const int SIZE = 5; int a[SIZE] = {5,21,14,2,3}; list<int> lst(a,a+SIZE); lst.sort(MyLess()); Print(lst,begin(),lst.end());//21,2,3,14,5 cout << endl; lst.sort(greater<lint>());//greater<int>()是個對象 Print(lst,begin(),lst.end());//21,14,5,3,2 cout << endl; }
關聯容器盒STL中許多算法,都是能夠用函數或函數對象自定義比較器的。在自定義了比較器op的狀況下,如下三種說法等價:
#include <iostream> #include <iterator> using namespace std; class MyLess{ public: bool operator()(int a1, int a2) { if((a1 % 10) < (a2 % 10)) return true; else return false; } }; bool MyCompare(int a1, int a2) { if((a1 % 10) < (a2 % 10)) return false; else return true; } int main() { int a[] = {35,7,13,19,12}; cout << *MyMax(a,a+5,MyLess()) << endl; //19 cout << *MyMax(a,a+5,MyCompare << endl; //12 return 0; } template <class T, class Pred> T MyMax(T first, T last, Pred myless) { T tmpMax = first; for(;first !=last;++first) if(myless(*tmpMax,*first)) tmpMax = first; return tmpMax; };
#include <iostream> #include <iterator> #include <set> using namespace std; int main() { int a[] = {8,7,8,9,6,2,1}; set<int> v(a,a+7); // 在此處補充你的代碼 ostream_iterator<int> o(cout," "); copy( v.begin(),v.end(),o); return 0; }
#include <iostream> #include <iterator> #include <list>//雙向鏈表 #include <vector> #include <string> using namespace std; list<int>& FindList(vector< list<int> >& l, int id) { int tmp = l.size(); vector< list<int> >::iterator i; i = l.begin(); return *(i + id - 1); } int main() { int n; cin >> n; vector< list<int> > a; for (int i = 0; i < n; i++) { string s; cin >> s; if(s == "new") { int id; cin >> id ; a.push_back(list<int>());//這個答案是默認id不會跳着設定…… } else if(s == "add") { int id, num; cin >> id >> num; list<int>& temp = FindList(a, id); temp.push_back(num); temp.sort();//將list中的元素按"<"規定的比較方法升序排列 } else if(s == "merge") { int id1, id2; cin >> id1 >> id2; list<int>& temp1 = FindList(a, id1); list<int>& temp2 = FindList(a, id2); temp1.sort(); temp2.sort(); temp1.merge(temp2); } else if(s == "unique") { int id; cin >> id; list<int>& temp = FindList(a, id); temp.sort(); temp.unique(); } else if(s == "out") { int id; cin >> id; list<int>& temp =FindList(a, id); temp.sort(); if (temp.size() > 0) { list<int>::iterator i; for (i = temp.begin(); i != temp.end(); i++) { cout << *i << " "; } } cout << endl; } } return 0; }