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)案例
- 需求分析
- 框架搭建
- 代码实现
