C++STL总结笔记(一)—— 容器和容器适配器

文章目录

  • 前言
  • 一、概念
    • 1.1 顺序容器
    • 1.2 容器适配器
    • 1.3 关联容器
  • 二、程序示例
    • 1. vector和Set自定义数据类型的访问
    • 2.vector容器嵌套
    • 3.list容器排序
    • 4.pair对组的使用
  • 总结


前言

STL是C++中的基于数据结构和算法的标准模板库,可以大量节约系统开发时间,增加程序复用性。
STL的六大件包括容器、算法、迭代器、仿函数、适配器和空间配置器,其中几乎所有代码均使用了模板类和模板函数的概念。

一、概念

容器从字面意思理解就是放东西的器件,C++中的容器是指将对象放入存储对象的模板类型里。
容器有以下几种:

1.1 顺序容器

顺序容器也叫序列式容器,是各元素之间存在顺序关系的线性表,其中元素的位置固定,但可用删除或插入的操作进行改变,这种操作称为质变算法。

顺序容器由vector(向量)、list(列表)、deque(队列)组成。

vector是最常见的容器类型,访问其中的数据有很多方法,这里使用迭代器完成,一般使用iterator迭代器,它是指针的泛化,声明的对象可以用*+对象完成查看。与普通数组的不同之处在于vector是可以动态扩展的数据结构,没有长度的限制,其原理是重新开辟新空间来拷贝原来的数组内容,然后删除原有空间。
其缺陷在于对头部进行插入或删除时效率较低。

//头文件
#include<vector>//定义容器
vector<int> v;
//插入数据
v.push_back(1);
v.push_back(3);
v.push_back(5);
//访问数据1
for (vector<int>::iterator i = v.begin(); i != v.end(); i++)
{cout << *i << endl;
}
//[]和at访问
cout << v[0] << endl;
cout << v.at(0) << endl;
//拷贝构造完成赋值
vector<int>v2(v);
v2.resize(3);
v2.insert(v2.begin(),100);
v2.erase(v2.begin());

deque(double-ended queue:双端队列)是一种对两端元素进行添加和删除操作的容器,又称双端数组,应用方式基本和vector一样。
其特点:
1: 采用多个连续的内存存储数据,并且在一个映射结构中保存对这些内存和顺序的跟踪,索引数组是存储每段数组的首地址。
2:和vevtor不同,deque向两端插入或删除元素时效率较高,但中间效率较低。
3:deque在访问元素时比vector慢。
4:deque的迭代器也支持随机访问数组元素。
工作原理:
deque是由一个中控器来维护缓冲区的地址,其中缓冲区存放数据。

	deque<int>d;for (int i = 0; i < 10; i++){d.push_back(i);}PrintDeque(d);deque<int>d1(d.begin(), d.end());PrintDeque(d1);//赋值deque<int>d2;d2 = d1;PrintDeque(d2);deque<int>d3;//尾插d3.push_back(1);//头插d3.push_front(2);PrintDeque(d3);d3.insert(d3.begin(), 3);PrintDeque(d3);deque<int>::iterator i = d3.begin();d3.erase(i);//默认从小到大sort(d3.begin(), d3.end());PrintDeque(d3);d3.clear();PrintDeque(d3);

list叫双向链表,其数据元素是通过链表指针串连成的线性表,由节点表示元素位置,节点由三部分组成,前驱元素指针域、数据域和后继元素指针域。前驱元素指针域保存了前驱元素的首地址;数据域则是本节点的数据;后继元素指针域则保存了后继元素的首地址。迭代器也是双向迭代器。
缺点:
1:由于list元素节点并不要求在一段连续的内存中,故不支持快速随机存取,只能通过“++”或“–”操作将迭代器移动到后继/前驱节点元素处。
2:遍历速度慢,是用指针进行读取的。
3:占用内存大。
优点:
1:可以快速的插入和删除数据。原因是list是通过指针指向来串联的,插入元素的时候只需要让前后的指针指向新的元素节点即可,不需移动元素位置。
2:采用动态分配内存,不会浪费。

	//构造函数list<int>l;l.push_back(1);l.push_back(2);l.push_back(3);
list<int>l2(l.begin(),l.end());PrintList(l2);list<int>l3(l2);PrintList(l3);list<int>l4(3,10);PrintList(l4);//赋值list<int>l5;l5 = l4;list<int>l6;l6.assign(l5.begin(), l5.end());list<int>l7;l7.assign(3, 10);PrintList(l7);//交换l.swap(l7);PrintList(l);PrintList(l7);//存取cout<<l.front()<<endl;cout << l.back() << endl;//list不支持随机访问list<int>::iterator i = l.begin();i++;//支持++,--访问元素i--;//反转l.swap(l7);l.reverse();PrintList(l);    

1.2 容器适配器

容器适配器包括stack,queue,priority_queue三种,可以让基本的容器类型采用另一种更适配于当前工作要求的工作方式实现。三种适配器都需满足一定的约束条件,也可以可理解为加了限制条件的容器。

stack称为栈容器,是以deque为底层容器,封闭一些功能而形成一种具有“先进后出”特性,并不允许遍历行为的容器适配器,所以stack没有迭代器。

    #include<stack>stack<int>s;//从栈顶入栈s.push(1);s.push(2);//判断栈顶是否为空,出栈while (!s.empty()){cout << s.top() << endl;s.pop();}cout << s.size()<<endl;

queue又称队列,必须符合先进先出原则,也不允许遍历成员,所以也没有迭代器。

#include<iostream>
#include<string>
#include<queue>
#include<algorithm>
using namespace std;void test()
{queue<int>s;//从队顶入队s.push(1);s.push(2);//判断队头是否为空,出队while (!s.empty()){cout << s.front()<< endl;cout << s.back()<<endl;s.pop();}cout << s.size() << endl;
}int main()
{test();system("pause");
}

priority_queue称为优先队列,自定义数据的优先级, 让优先级高的排在队列前面, 可以优先出队。

#include <queue>priority_queue<int> a;for (int i = 0; i < 10; i++){a.push(i);}while (!a.empty()){cout << a.top() << ' ';a.pop();}cout << endl;

1.3 关联容器

关联容器是一种二叉树的结构,没有严格的顺序关系,元素位置会按照二叉树的排序方式进行,在排序的时候按照升序排列。
主要包含有三种,set(集合),multiset(多重集合),map,multimap。

set和multiset均可以进行快速查找数据,但区别在于set容器不允许有重复值,multiset可以有。
set在内存中是通过链表进行排序的,所以插入时比vector和deque要快,但是比list慢;在访问元素上比vector 慢,比list快,原因是list 是逐个搜索,它搜索的时间是跟容器的大小成正比,而关联容器 查找的复杂度是Log(N) ,比vector少。

void printSet(set<int>&s)
{for (set<int>::iterator i = s.begin(); i != s.end(); i++){cout << *i << " ";}cout << endl;
}
//降序.声明仿函数
class Comparedown
{
public:bool operator()(int a, int b)const{return a > b;}
};int main()
{set<int>s;//只能使用insert方法插入数据s.insert(1);s.insert(2);s.insert(3);//遍历容器printSet(s);//拷贝构造set<int>s2(s);printSet(s2);//赋值set<int>s3;s3 = s2;printSet(s3);//插入s.insert(4);s.erase(s.begin());s.erase(2);printSet(s);//互换s.swap(s2);//查找set<int>::iterator i = s.find(3);if (i!= s.end()){cout << *i << endl;}else{cout << "null" << endl;}//统计int n = s.count(3);cout << n << endl;//排序set<int, Comparedown>s5;s5.insert(3);s5.insert(2);for (set<int, Comparedown>::iterator i = s5.begin(); i != s5.end(); i++){cout << *i << " ";}//多重集合multiset<int>ms;ms.insert(1);ms.insert(1);for (multiset<int>::iterator i = ms.begin(); i != ms.end(); i++){cout << *i << " ";}
}

map 提供一种“键-值”关系的一对一的数据存储能力,所有元素都是pair类型。
pair的第一个元素是键值,第二个为value值。
键值即索引值,在容器中不可重复,其内部按链表的方式存储,故也继承了链表的优缺点,在插入时所有元素都会根据键值自动排序。
与set相似,multimap可以实现重复数据的存储。

void printMap(map<int,int>&m)
{for (map<int,int>::iterator i = m.begin(); i != m.end(); i++){cout <<"key=" << (*i).first <<" " <<"value=" << i->second<<endl;}cout << endl;
}class Comparedown
{
public:bool operator()(int a, int b)const{return a > b;}
};void test()
{map<int, int>m;//插入数据m.insert(pair<int, int>(1, 2));m.insert(pair<int, int>(3, 4));m.insert(make_pair(2, 6));m.insert(make_pair(5, 34));m.insert(map<int, int>::value_type(7, 8));printMap(m);//拷贝构造map<int, int>map1(m);//赋值map<int, int>map2;map2 = m;//按key进行删除m.erase(1);printMap(m);//按key查找map<int, int>::iterator i = m.find(3);if (i != m.end()){cout << i->first << i->second << endl;}else{cout << "未找到" << endl;}//统计key,但key不重复,所以n值为0或1int n = m.count(3);cout << n << endl;//用仿函数完成从大到小排序map<int, int,Comparedown>map4;map4.insert(make_pair(2, 6));map4.insert(make_pair(6, 6));map4.insert(make_pair(3, 6));for (map<int, int, Comparedown>::iterator i = map4.begin(); i != map4.end(); i++){cout << "key=" << (*i).first << " " << "value=" << i->second << endl;}
}int main()
{test();system("pause");
}

二、程序示例

1. vector和Set自定义数据类型的访问

class Person
{
public:Person(string name, int age){this->Name = name;this->Age = age;}string Name;int Age;
};
//存数据
void test()
{//vectorvector<Person> v;Person p1("sun", 4);Person p2("aun", 3);Person p3("cun", 2);Person p4("dun", 1);v.push_back(p1);v.push_back(p2);v.push_back(p3);v.push_back(p4);for (vector<Person>::iterator i = v.begin(); i != v.end(); i++){cout << (*i).Name <<"  " <<(*i).Age<<endl;cout << i->Name << "  " << i->Age << endl;}//setset<Person> s;Person p1("sun", 4);Person p2("aun", 3);Person p3("cun", 2);Person p4("dun", 1);
}//存指针
void test1()
{vector<Person*> v;Person p1("sun", 4);Person p2("aun", 3);Person p3("cun", 2);Person p4("dun", 1);v.push_back(&p1);v.push_back(&p2);v.push_back(&p3);v.push_back(&p4);for (vector<Person*>::iterator i = v.begin(); i != v.end(); i++){cout << (*(*i)).Name <<" " << (*(*i)).Age<< endl;cout << (*i)->Name << " " << (*i)->Age << endl;}
}

2.vector容器嵌套

void test()
{vector<vector<int>>doublev;//创建内层容器vector<int>doublev1;//放数据for (int i = 0; i < 3; i++){doublev1.push_back(i + 1);}//放入外层容器doublev.push_back(doublev1);//遍历数据for (vector<vector<int>>::iterator i = doublev.begin(); i != doublev.end(); i++){for (vector<int>::iterator j = (*i).begin(); j != (*i).end(); j++){cout << *j << endl;cout << &j << endl;//内层嵌套的迭代器指针地址}cout << &i << endl;//外层嵌套的迭代器指针地址}
}

3.list容器排序

class Cat
{
public:Cat(string name, int color,int age){this->Name = name;this->Color = color;this->Age = age;}public:string Name;int Color;int Age;
};//指定排序规则
bool Compare(Cat& c1, Cat& c2)
{if (c1.Color == c2.Color){return c1.Age < c2.Age;}else{return c1.Color < c2.Color;}	
}void test()
{list<Cat>L;Cat cat1("小100", 76, 3);Cat cat2("小200", 32, 2);Cat cat3("小300", 32, 4);Cat cat4("小400", 32, 3);Cat cat5("小500", 54, 1);//插入L.push_back(cat1);L.push_back(cat2);L.push_back(cat3);L.push_back(cat4);L.push_back(cat5);for (list<Cat>::iterator i = L.begin(); i != L.end(); i++){cout << (*i).Name << " " << (*i).Color << " " << (*i).Age << endl;}L.sort(Compare);for (list<Cat>::iterator i = L.begin(); i != L.end(); i++){cout << (*i).Name << " " << (*i).Color << " " << (*i).Age << endl;}
}int main()
{test();system("pause");
}

4.pair对组的使用

pair是一个模板结构体类型,set集合的insert方法就是pair类模板定义的,pair的参数类型有两种,一个是迭代器,另外一个是bool类。bool返回迭代器是否应用方法成功,pair里的对象可以由pair的两个函数first和second访问。

multiset只返回迭代器类型,故可以重复插入。

//set
pair<iterator, bool> insert(value_type&& _Val) 
{const auto _Result = _Emplace(_STD move(_Val));return {iterator(_Result.first, _Get_scary()), _Result.second};
}
//pair定义
struct pair { // store a pair of values
using first_type  = _Ty1;
using second_type = _Ty2;//multiset
iterator insert(value_type&& _Val)
{return iterator(_Emplace(_STD move(_Val)).first, _Get_scary());
}
//
pair<set<int>::iterator, bool> p = s.insert(4);
if (p.second)//first返回迭代器,second返回bool
{cout << "插入成功" << endl;
}

pair既可以将2个数据组合成一组数据,也可以让函数返回2个数据,具体应用如下:

	pair<string, int> p1(string("a"), 3);cout << p1.first << p1.second << endl;pair<string, int> p2 = make_pair(string("a"), 3);cout << p2.first << p2.second << endl; 

总结

容器的构造函数和成员函数的调用规则基本是类似的,但每种都会存在一点差别,重点记忆vector, list,map三种的调用方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/256111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图像处理】——比特平面原理和实现方法(全网较全面,含所有比特位图的分层方法)

目录 一、比特平面 1st比特平面:括号里面的为比特值,前面的是原图像中对应要变为0的像素值

20145238-荆玉茗 《信息安全系统设计基础》第7周学习总结

20145238 《信息安全系统设计基础》第7周学习总结 教材学习内容总结 存储器系统 : 存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构。 1、RAM随机访问存储器 分类&#xff1a;SRAM&#xff08;静态&#xff09;、DRAM&#xff08;动态&#xff09;特点&…

关于两个jar包中存在包名和类名都完全相同的jar包冲突问题

2019独角兽企业重金招聘Python工程师标准>>> 最近弄webservice&#xff0c;我使用的jdk自带的wsimport工具来生成客户端代码&#xff0c;发现生成的代码具有编译错误&#xff0c;错误描述如下&#xff1a; The method getPort(QName, Class<T>) in the type S…

限制文本框只能输入数字和小数点

<input type"text" class"NumText" placeholder"只能输入数字&#xff08;可含有小数点&#xff09;"/><style> .NumText{width:200px;} .NumText::-webkit-input-placeholder{color:#F1923C;} .NumText:-moz-placeholder{…

C++STL总结笔记(二)——仿函数(函数对象)

文章目录一、概念总结一、概念 仿函数又称函数对象&#xff0c;即重载了函数调用运算符&#xff08;&#xff09;的类的对象。 优势&#xff1a; 1.仿函数对象的内部可以有自己的状态&#xff0c;可以实现一些其他的功能。 2.函数对象可以作为参数进行传递。 当仿函数类内重载…

【图像处理】——灰度变换心得(cv2.normalize规范化值0-255,cv2.convertScaleAbs(new_img)转为8位图)

目录 一、灰度变换函数 对数变换 加码变换 常见雷点 常见灰度变换函数

SQL Server2008 表旋转(pivot)技术

参考资料&#xff1a; http://www.cnblogs.com/xiashengwang/p/3503554.html转载于:https://www.cnblogs.com/lihuali/p/6014776.html

const和define 区别

1&#xff1a; 编译器处理不同 define宏是在预处理阶段展开&#xff0c;const常量是编译运行阶段使用。 2&#xff1a;类型和安全检查不同 const常量有数据类型&#xff0c;而宏常量没有数据类型&#xff0c;仅仅是展开。编译器可以对前者进行类型安全检查&#xff0c;而对后者…

学习笔记(三)

一.调试模式 define(APP_DEBUG, true); 调试模式的优势在于&#xff1a; 开启日志记录&#xff0c;任何错误信息和调试信息都会详细记录&#xff0c;便于调试&#xff1b;  关闭模板缓存&#xff0c;模板修改可以即时生效&#xff1b;  记录SQL日志&#xff0c;方便分析SQL…

【项目实战】——Python打包正装换底色代码为exe文件(可在其他无Python环境下运行)

目录 1.安装pyinstaller 2.生成.exe文件 方法1&#xff1a; 方法2&#xff1a; 方法3&#xff1a; &#xff08;1&#xff09;使用命令行窗口进入项目的根目录 &#xff08;2&#xff09;在改目录下执行pyi-makespec main.py&#xff08;main.py是你的主入口文件&#x…

C++STL总结笔记(三)—— 常见算法

文章目录一、基本概念二、程序示例1.遍历2. 查找3. 排序、拷贝、替换4. numeric相关算法总结一、基本概念 算法是STL中很重要的一部分&#xff0c;其功能包括比较&#xff0c;查找&#xff0c;排序&#xff0c;交换&#xff0c;遍历&#xff0c;复制等等。 最大的算法头文件是…

Java zip解压,并遍历zip中的配置文件 .cfg或.properties

1.解析cfg或properties配置文件 讲配置文件&#xff0c;读取&#xff0c;并封装成为map类型数据 /*** 解析cfg文件** param cfgFile* return*/public static Map<String, Object> readCfg(FileInputStream cfgFile) {Properties prop new Properties();Map<String, O…

db2 常用配置

db2set配置&#xff1a; db2set DB2_ENABLE_LDAPNO db2set DB2_ALTERNATE_GROUP_LOOKUPGETGROUPLIST db2set DB2_RESTORE_GRANT_ADMIN_AUTHORITIESON db2set DB2_SKIPINSERTEDON db2set DB2_LOAD_COPY_NO_OVERRIDENONRECOVERABLE db2set DB2_EVALUNCOMMITTEDON db2set DB2_SKIP…

安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(三)码农网

12. 安装 Apache Tomcat Tomcat 是由 Apache 设计的用来运行 Java HTTP web 服务器的 servlet 容器。按照下面的方法安装 tomcat&#xff0c;但需要指出的是安装 tomcat 之前必须先安装 Java。 # yum install tomcat 安装 Apache Tomcat 安装完 tomcat 之后&#xff0c;启动 to…

【图像处理】——图像特效处理(马赛克、图像融合、毛玻璃等)

参考:https://blog.csdn.net/qq_43328040/article/details/109081414 import cv2 import numpy as np import random#马赛克:将一定大小窗口的RGB设置成一个颜色 def horseBox(img):row,col,chal = img.shapeboxRow = int(0.3*row)boxcol = int(0.3*col)for m in range(50,b…

JDK5.0新特性之:泛型

文/陈刚 2005-11-09 一、前言 泛型这个词在现在的JAVA挺时髦&#xff0c;光从字面上你是无法知道它代表些什么东东的&#xff0c;所以我们还是不要从字面去理解&#xff0c;而是从一些实例去了解它吧。 二、泛型之前的日子 &#xff2a;&#xff24;&#xff2b;&#xff11;.…

QT5.14.2基于PCL1.11.1显示点云(基于Windows VS2019开发环境)

文章目录一、安装1.1 PCL安装1.2 QT安装1.3 VTK编译二、程序配置1. 基于mscv创建QT的程序2. 配置QT工程文件和依赖项3. 编写点云显示的小程序总结一、安装 1.1 PCL安装 PCL1.11.1库的安装网上教程很多&#xff0c;推荐一个很好的教程&#xff1a; Win10 系统下 VisualStudio2…

Spring学习笔记—最小化Spring XML配置

自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素&#xff0c;让Spring自动识别如何装配Bean的依赖关系。 自动检测(autodiscovery)比自动装配更进了一步&#xff0c;让Spring能够自动识别哪些类需要被配置成Spring Bean&#xf…

【数据结构】——快速排序

目录 一、代码 二、复杂度&#xff1a;O(nlog(n)) 三、快速排序的劣势 视频参考链接&#xff1a;https://www.bilibili.com/video/BV1mp4y1D7UP?p17 一、代码 思想&#xff1a;假设是对一个list进行排序 1、选取第一个元素作为p元素&#xff1b; 2、将p元素归位&#xff0…

读取数据库信息构建视图字段的备注信息,方便程序代码生成

在很多情况下&#xff0c;我们开发都需要有一个快速的代码生成工具用来提高开发效率&#xff0c;代码生成工具很多信息都是读取数据库的表、视图等元数据进行对象表信息的完善&#xff0c;有了这些信息&#xff0c;我们就可以在普通的实体类代码里面添加属性字段的中文注释&…