容器:可容纳各类数据类型的通用数据结构,是类模版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; }