版权声明:请注明转发出处 https://blog.csdn.net/mafucun1988/article/details/89630962
1. STL 介绍
STL(standard template library)是一个具有工业强度的高效C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。
- 从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming),引入了诸多新的名词,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。与OOP(object-oriented programming)中的多态(polymorphism)一样,泛型也是一种软件的复用技术;
- 从实现层次看,整个STL是以一种类型参数化(type parameterized)的方式实现的,这种方式基于一个在早先C++标准中没有出现的语言特性--模板(template)。如果查阅任何一个版本的STL源代码,你就会发现,模板作为构成整个STL的基石是一件千真万确的事情。除此之外,还有许多C++的新特性为STL的实现提供了方便
2. STL的六大组件
- 容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;
- 迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象;
- 算法(Algorithm),是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
- 仿函数(Function object,仿函数(functor)又称之为函数对象(function object),其实就是重载了()操作符的struct,没有什么特别的地方
- 迭代适配器(Adaptor)
- 空间配制器(allocator)其中主要工作包括两部分1.对象的创建与销毁 2.内存的获取与释放
3. 容器比较
容器 | vector | deque | list | set | multiset | map | multimap |
---|---|---|---|---|---|---|---|
内部结构 | dynamic array | array of arrays | double linked list | binary tree | binary tree | binary tree | binary tree |
随机存取 | yes | yes | no | no | no | yes(key) | no |
搜索速度 | 慢 | 慢 | 很慢 | 快 | 快 | 快 | 快 |
快速插入移除 | 尾部 | 首尾 | 任何位置 | -- | -- | -- | -- |
4. 容器介绍
- 1)动态数组vector
- 创建一个容器 动态数组 指定这个容器中放的数据类型 都是Int
- 通过vector通过成员方法 向容器的尾部添加元素
- 拿到了指向第一个元素的迭代器
- 返回指向最后一个元素下一个位置
- 创建一个容器 指定里面放Teacher类型的数据
- vector构造函数
- vector赋值操作
- vector容器的插入和删除
//容器
vector<int> v; //创建一个容器 动态数组 指定这个容器中放的数据类型 都是Int
v.push_back(10); //通过vector通过成员方法 向容器的尾部添加元素
v.push_back(4);
v.push_back(5);
v.push_back(4);
vector<int> v; //默认构造 空的vector容器
vector<int> v2(10,5); //带参数构造函数
vector<int> v3(v2.begin(), v2.end());
vector<int> v4(v3); //拷贝构造
int arr[] = {2,3,6,7};
vector<int> v5(arr,arr+ sizeof(arr)/sizeof(int));
//vector赋值操作
vector<int> v;
v.assign(5,1); //赋值方法
vector<int> v1;
v1.assign(v.begin(),v.end()); //将容器V中元素赋值给v1
vector<int> v2;
v2 = v1;
cout << "大小:" << v.size() << endl;
cout << "容量" << v.capacity() << endl;
//插入删除
int arr[] = { 6, 8, 3, 9 };
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));
v.insert(v.begin(),100); //头部插入元素
v.push_back(100); //尾插法
int val = v.back();
cout << val << "被删除" << endl;
v.pop_back();
//指定位置删除
v.erase(v.begin());
//区间删除
v.erase(v.begin(),v.end());
v.clear();
//迭代器
vector<int>::iterator pStart = v.begin(); //拿到了指向第一个元素的迭代器
vector<int>::iterator pEnd = v.end(); //返回指向最后一个元素下一个位置
while (pStart != pEnd){
cout << *pStart << " ";
pStart++;
}
cout << endl;
//count统计容器中某个元素的个数
int n = count(v.begin(),v.end(),4);
cout << "n:" << n << endl;
vector<Teacher> v; //创建一个容器 指定里面放Teacher类型的数据
Teacher t1(1, 2), t2(3, 4), t3(5, 6);
v.push_back(t1);
v.push_back(t2);
v.push_back(t3);
vector<Teacher>::iterator pStart = v.begin(); //拿到指向第一元素的迭代器
vector<Teacher>::iterator pEnd = v.end();//指向最后一个元素下一个位置
while (pStart != pEnd){
Teacher t = *pStart;
cout << "ID:" << t.ID << " AGE:" << t.age << endl;
pStart++;
}
- 2)字符串string
- string类型转换为char*字符串
- char*类型字符串转换为string类型字符串
- string初始化
- string容器字符串赋值和存取
- string容器拼接操作
- string查找和替换 比较
- string 比较 子串 插入和删除
//string类型转换为char*字符串
string s = "abc";
const char* str = s.c_str();
//char*类型字符串转换为string类型字符串
char* str2 = "acbd";
string s2(str2);
string s; //默认构造
string s2 = "acbd";
string s3(s2);
string s4(10, 'c');
//string容器赋值
string s;
s = "abcd";
string s2;
s2.assign("pppp");
//string容器存取
string s3 = "abcdefg";
//[]访问方式访问越界时候,不会抛异常,直接挂掉
//at会抛出异常
try{
//cout << s3[100] << endl;
cout << s3.at(100) << endl;
}
catch (...){
cout << "访问越界!" << endl;
}
string s1 = "aaa";
string s2 = "bbb";
string s3 = s1 + s2;
s1 += s2;
//成员方法方式 append
s1.append(s2);
string s = " acbdefg";
//查找
string target = "bd";
int pos = s.find(target);
char* target2 = "ef";
int pos2 = s.find(target2);
//从后往前查找
int pos3 = s.rfind(target);
//字符串替换
string s1 = "acbd";
s.replace(0, 2, s1);
//比较
string s1 = "abc";
string s2 = "abd";
int ret = s1.compare(s2);
//子串
string s3 = "abcdefg";
string s4 = s3.substr(0,2);
//插入和删除
string s5 = "abcd";
s5.insert(0, "pppp");
string s6 = "qqqq";
s5.insert(s5.size(), s6);
s5.erase(0,4);
- 3)双向数组 deque
- 初始化
- 赋值操作
- 大小操作
- 插入和删除
//初始化
deque<int> d1; //默认构造函数
deque<int> d2(10,5); //带参数构造函数
deque<int> d3(d2.begin(),d2.end());
deque<int> d4(d3); //拷贝构造
//赋值操作
deque<int> d1(10, 3);
deque<int> d;
d.assign(10,5); 赋值
d.assign(d1.begin(),d1.end());
d = d1; //重载= 赋值
//大小操作
deque<int> d1(10, 3);
int size = d1.size();
bool isEmpty = d1.empty();
d1.resize(15);
//插入和删除
deque<int> d;
d.push_back(10);
d.push_back(20);
d.push_front(30);
d.push_front(40);
//第一种遍历方式
for (int i = 0; i < d.size();i++){
cout << d[i] << " ";
}
//第二种遍历方式
for (int i = 0; i < d.size(); i++){
cout << d.at(i) << " ";
}
//第三种方式
for (deque<int>::iterator it = d.begin(); it != d.end(); it++){
cout << *it << " ";
}
//尾删除
while (d.size() > 0){
cout << d.back() << "被删除!" << endl;
d.pop_back();
}
//头删除
while (!d.empty()){
cout << d.front() << "被删除!" << endl;
d.pop_front();
}
deque<int> d;
d.insert(d.begin(),100); //头插法
d.insert(d.end(), 200); //尾差法
- 4)集合set
- 初始化
- set容器插入和删除
- set容器查找
//初始化
set<int> myset; //默认构造
set<int> myset2(myset); //拷贝构造
//set容器插入和删除
set<int> myset; //默认从小到大排序
myset.insert(4);
myset.insert(2);
myset.insert(1);
myset.insert(5);
myset.insert(3);
myset.erase(myset.begin()); //删除第一个元素
myset.erase(2); //根据元素值删除
myset.erase(myset.begin(),myset.end()); // myset.clear()
int size = myset.size();
//插入函数对象
class mycompare04{
public:
bool operator()(Teacher t1, Teacher t2){
return t1.id > t2.id;
}
};
set<Teacher, mycompare04> myset;
Teacher t1(1, 2), t2(3, 4), t3(5, 6);
myset.insert(t1);
myset.insert(t2);
myset.insert(t3);
for (set<Teacher, mycompare04>::iterator it = myset.begin(); it != myset.end();it ++){
cout << it->id << " " << it->age << endl;
}
cout << endl;
set<Teacher, mycompare04>::iterator pos = myset.find(Teacher(3, 4));
if (pos == myset.end()){
cout << "没有查找到!" << endl;
}
else{
cout << "查找到:" << pos->id << ":" << pos->age << endl;
}
//设置从大到小排序
template<class T>
class mycompare03{
public:
bool operator()(T v1,T v2) const{
return v1 > v2;
}
};
set<int, mycompare03<int>> myset;
myset.insert(4);
myset.insert(2);
myset.insert(1);
myset.insert(5);
//set容器查找
set<int>::iterator pos = myset.find(20); //返回值为2的元素所在的位置
if (pos == myset.end()){
cout << "没有查找到!" << endl;
}
else{
cout << "查找到:" << *pos << endl;
}
set<int> myset;
myset.insert(10);
myset.insert(5);
myset.insert(1);
myset.insert(8);
set<int>::iterator pos = myset.lower_bound(5); //返回大于等于5 迭代器
if (pos == myset.end()){
cout << "没有找到!" << endl;
}
else{
cout << "找到:" << *pos << endl;
}
pos = myset.upper_bound(5);//返回大于5 迭代器
if (pos == myset.end()){
cout << "没有找到!" << endl;
}
else{
cout << "找到:" << *pos << endl;
}
pair<set<int>::iterator, set<int>::iterator> pos2 = myset.equal_range(5);//返回大于等于5 迭代器 + 返回大于5 迭代器
if (pos2.first == myset.end()){
cout << "meiyouzhaodao!" << endl;
}
else{
cout << "zhaodao!" << *(pos2.first) << endl;
}
if (pos2.second == myset.end()){
cout << "meiyouzhaodao!" << endl;
}
else{
cout << "zhaodao!" << *(pos2.second) << endl;
}
- 5)对组 pair
- 初始化
//第一种方式 创建一个pair
pair<int, string> mypair(10,"aaa");
cout << mypair.first << endl;
cout << mypair.second << endl;
//第二种 创建pair
pair<string,string> mypair2 = make_pair("aaa","bbb");
//auto mypair2 = make_pair("aaa", "bbb");
cout << mypair2.first << " " << mypair2.second << endl;
//第三种
pair<int, string> mypair3 = mypair; //拷贝构造
- 6)多集合 mutliset(允许多个重复元素共存)
- 初始化
- 插入
- 遍历
multiset<int> muset;
muset.insert(10);
muset.insert(20);
muset.insert(5);
muset.insert(35);
muset.insert(5);
for (multiset<int>::iterator it = muset.begin(); it != muset.end();it ++){
cout << *it << " ";
}
- 7)映射 map
- 初始化
- 插入操作
- 删除和查找
//初始化
//map容器的模板参数 需要指定key类型 value类型
map<int, string> mymap; //默认构造
map<int, string> mymap2(mymap); //拷贝构造
//插入操作
map<int, int> mymap;
//第一种插入方式
mymap.insert(pair<int, int>(1, 5));
//第二种
pair<map<int, int>::iterator, bool> ret = mymap.insert(make_pair(2, 10));
if (ret.second){
cout << "插入成功!" << endl;
}
else{
cout << "插入失败!" << endl;
}
//第三种
mymap.insert(map<int, int>::value_type(3,15));
//第四种,有则修改,无则添加
mymap[4] = 20;
//删除和查找
map<int, int> mymap;
mymap.insert(make_pair(1, 2));
mymap.insert(make_pair(2, 3));
mymap.insert(make_pair(3, 4));
mymap.erase(2); //根据Key删除元素
print(mymap);
mymap.erase(mymap.begin()); //删除第一个元素
print(mymap);
mymap.erase(mymap.begin(),mymap.end()); // mymap.clear
cout << "map size:" << mymap.size() << endl;
//查找
map<int, int>::iterator pos = mymap.find(3);
if (pos == mymap.end()){
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos->first << " value:" << pos->second << endl;
}
cout << "---------------" << endl;
pos = mymap.lower_bound(2);
if (pos == mymap.end()){
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos->first << " value:" << pos->second << endl;
}
pos = mymap.upper_bound(2);
if (pos == mymap.end()){
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos->first << " value:" << pos->second << endl;
}
pair<map<int, int>::iterator, map<int, int>::iterator> pos2 = mymap.equal_range(2);
if (pos2.first == mymap.end()){ //第一个迭代器
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos2.first->first << " value:" << pos2.first->second << endl;
}
if (pos2.second == mymap.end()){ //第二个迭代器
cout << "没有找到!" << endl;
}
else{
cout << "查找到:" << pos2.second->first << " value:" << pos2.second->second << endl;
}
- 8)多映射 multimap
- 初始化
- 插入和删除
- 查找
//初始化
multimap<int, QString> Ygroup; //存放分组后的员工信息
//插入信息
group.insert(make_pair(1,"Test1"));
group.insert(make_pair(2,"Test2"));
group.insert(make_pair(2,"Test3"));
group.insert(make_pair(4,"Test4"));
//查找信息
multimap<int, QString>::iterator pos = group.find(2);
int count = group.count(2);
int num = 0;
while (pos != group.end() && num < count){
cout << "姓名: " << pos->second.name << endl;
num++;
pos++;
}