stl容器注意点总结
1、容器共性
除了queue和stack之外,每个容器都提供了可返回的迭代器函数,运用返回的迭代器就可以访问元素
通常stl不会抛出异常,需要使用者传入正确的参数
每个容器都提供一个默认的构造函数和默认的拷贝构造函数
大小相关的构造方法size(),empty();
| vector | deque | list | set | multiset | map | multimap |
典型内存结构 | d单端数组 | s双端数组 | s双向链表 | e二叉树 | 二叉树 | 二叉树 | 二叉树 |
可随机存取 | yes | yes | no | no | no | d对key而言yes | no |
元素搜寻速度 | low | low | very low | fast | fast | 对key而言fast | 对key而言fast |
元素安插移除 | w尾端 | t头尾两端 | r任何位置 | | | | |
2、函数对象问题
stl容器提供值(value)寓意,而非引用寓意,也就是说当我们给容器中插入元素的时候,容器内部实施了拷贝动作,将我们要插入的元素再另行拷贝一份放到容器中,而不是将原先数据元素直接放进容器中,也就是说我们提供的元素必须能够被拷贝
3、stl内建函数对象
使用内建函数,需要引入#include<functional>
6个算数类函数对象,除了negate是一元运算,其他都是二元运算
template<class T> T plus<T>//加法仿函数
template<class T> T minute<T>//减法仿函数
template<class T> T multiplies<T>//乘法仿函数
template<class T> T divides<T>//除法仿函数
template<class T> T modulus<T>//取模仿函数
template<class T> T negate<T>//取反仿函数
6个关系运算类函数对象,每一种都是二元运算
template<class T> bool equal_to<T>//等于
template<class T> bool not_equal_to<T>//不等于
template<class T> bool greater<T>//大于
template<class T> bool greater_equal<T>//大于等于
template<class T> bool less<T>//小于
template<class T> bool less_equal<T>//小于等于
逻辑运算类函数,not为一元运算,其余为二元运算
template<class T> bool logical_and<T>//
template<class T> bool logical_or<T>//
template<class T> bool logical_not<T>//
4、函数对象适配器
bind1st:将参数绑定为函数对象的第一个参数
bind2st:将参数绑定为函数对象的第二个参数
not1:对一元函数对象取反
not2:对二元函数对象取反
ptr_fun:将普通函数修饰成函数对象
mem_fun:修饰成员函数
mem_fun_ref:修饰成员函数
自定义函数对象和预定义函数对象
#include<iostream> #include<vector> #include<string> #include<algorithm> #include<functional> using namespace std; //bind1st bind2nd //第一步 需要让你自定义函数对象去继承父类 binary_function unary_function class print:public binary_function<int,int,void>{ public: void operator()(int v,int v2) const{ cout << "v:" << v << "v2" << v2 << endl; if (v>v2) cout << v << " "; } }; void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } print p; for_each(v.begin(), v.end(), bind1st(p,5); cout << endl; //bind2st bind2nd绑定适配器 调用绑定适配器,统统编程一元函数对象 } //not1 not2取反适配器 struct mycompare02{ bool operator()(int v){ return v > 5; } }; void test02() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector<int>::iterator pos = find_if(v.begin(), v.end(), mycompare02); if (pos != v.end()){ cout << "找到" << *pos << endl; } else { cout << "meiyouzhaodao" << endl; } } void test03() { } void test04() { } int main() { test01(); return EXIT_SUCCESS; }
#include<iostream> #include<functional> #include<string> #include<vector> #include<algorithm> using namespace std; void print(int v){ cout << v << " "; } void test01() { plus<int> myplus; int ret = myplus(10, 20); cout << ret << endl; plus<string> myplus2; string s1 = "aaa"; string s2 = "bbb"; string ret2 = myplus2(s1, s2); cout << ret2 << endl; cout << plus<int>()(10, 20) << endl; } //transform void test02() { vector<int> v1,v2,v3; for (int i = 0; i < 10; i++) { v1.push_back(i); v2.push_back(i + 1); } v3.resize(v1.size()); //plus<int> myplus; for_each(v3.begin(), v3.end(), print); cout << endl; transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), plus<int>()); for_each(v3.begin(), v3.end(), print); cout << endl; } int main() { //test01(); test02(); return EXIT_SUCCESS; }
4、容器深拷贝和浅拷贝
#include<iostream> #include<vector> #include<string> using namespace std; class Teacher{ public: Teacher(char *name, int age){ int len = strlen(name) + 1; this->name = new char[len];//在堆分配内存 strcpy(this->name, name); this->age = age; } //拷贝构造 Teacher(const Teacher& t){ int len = strlen(t.name) + 1; this->name = new char[len]; strcpy(this->name, t.name); this->age = t.age; } //重载 Teacher& operator=(Teacher& t){ int len = strlen(t.name) + 1; if (this->name != NULL){ delete[] this->name; } this->name = new char[len]; strcpy(this->name, t.name); this->age = t.age; return *this; } ~Teacher(){ if (this->name!=NULL){ delete[] this->name; } this->age = 0; } char *name; int age; }; void test01() { Teacher t1("aaa", 20); vector<Teacher> v; v.push_back(t1); } int main() { test01(); return EXIT_SUCCESS; }
6、stl总结
(1)stl迭代器是对普通指针做了一层封装
- string容器
- vector容器:单口动态数组,在尾部插入删除效率非常高,在头部或中间插入和删除效率非常低(要移动数据)
vector动态增长:1、发现空间不足,重新申请内存,2、将原空间的数据拷贝到新空间,旧的空间释放掉,
resize和reserve,resize重新开辟空间,并且初始化,reserve不初始化只开辟空间
- deque容器:双端数组,在两端插入和删除效率都非常高,求两个迭代器直接距离distance()
- stack:先进后出,不提供迭代器,因为会破坏先进后出规则
- queue:先进先出,不提供迭代器,因为会破坏先进后出规则
- list:双向链表,结点和结点之间是通过指针相连,插入和删除元素都不会有数据移动,
- set/multiset:红黑树,对元素自动进行排序
- map/multimap:红黑树,键值操作,map根据key进行排序,不能有重复元素,map插入四种方法,对组pair进行实现
二叉搜索树和平衡二叉树
(2)函数对象
一元函数对象
二元函数对象
一元谓词
二元谓词:两个参数,返回值为bool类型
函数对象适配器
(3)常用算法
- 遍历算法:
- 查找算法:
- 排序算法:
- 常用拷贝算法和替换算法
- 常用算数生成算法
- 常用集合算法
(4)案例
- 需求分析
- 框架搭建
- 代码实现