链接www.cnblogs.com/zhouzhendong/p/STL.html

C++ STL 的一些基础用法

本文摘抄并整理自cppreference

前言

​ 创建一个空的 vector ,我一直是这样写的:

vector <int> v;
v.clear();

​ 直到后来:

vector <int> v;

​ 在 vector 里创建一个 \(0\cdots n-1\) 的数列,我一直是这样写的:

vector <int> v(0);
for (int i=0;i<n;i++)
v.push_back(i);

​ 直到后来:

vector <int> v(n);
iota(v.begin(),v.end(),0);

​ 我发现我根本不会用 STL,于是我决定去学一学,于是就有了这篇文章。

​ 本文介绍一些常用的 STL 。

​ 设 a,b 为两个迭代器,接下来默认 [a,b) 表示位于 a~b-1 的迭代器。

​ 接下来所有变量名中,it,it1,it2,... 一般代表迭代器,x,v,... 一般代表类型为 int 的值。

1. vector

​ 于是我们从最常用的 vector 开始。

​ vector 的实现基于动态数组,结合倍增思想(空间开不下了就全部删掉再开 2 倍)。

​ 单次操作复杂度基本都是均摊 \(O(1)\) 的。

1.1 初始化

vector <int> a;//新建一个空的vector
vector <int> b(5,3);//新建一个包含 5 个 3 的 vector
vector <int> c(5);// = vector <int> c(5,0);
vector <int> d(b.begin()+1,b.end()-1);// 用 [b.begin()+1,b.end()-1) 这一段构成的数组生成 vector
vector <int> e(d);// 生成一个和 d 相同的 vector e

1.2 back

​ 设 v 为一个 vector v.back() 返回 v 的最后一个元素的引用。

​ 例如

vector <int> v;
v.push_back(3);
cout<<v.back()<<endl;
v.push_back(5);
cout<<v.back()<<endl;

​ 的输出结果是

3
5

1.3 begin

​ 设 v 为一个 vector v.begin() 返回一个迭代器,指向 v 第一个元素。

1.4 clear

v.clear() 表示将 v 清空(内存不释放)。

1.5 end

​ 设 v 为一个 vector v.end() 返回一个迭代器,指向 v 最后一个元素的后一个位置。

1.6 empty

​ 设 v 为一个 vector v.empty() 返回一个布尔值,表示 v 是否为空。

1.7 erase

vector <int> v(10);
iota(v.begin(),v.end(),1);
v.erase(v.begin()+5);//删除 v.begin()+5 这个位置的元素
v.erase(v.begin(),v.begin()+3);//删除 [v.begin(),v.end()) 这个区间之间的所有元素
for (auto i : v)
cout<<i<<" ";

​ 输出结果为

4 5 6 8 9 10

1.8 front

​ 设 v 为一个 vector ,则 v.front() 返回 v 的第一个元素的引用。

1.9 insert

vector <int> v(3,1);
vector <int> :: iterator it=v.begin();
it=v.insert(it,2);//在 it 处插入一个 2
v.insert(it,2,3);//在 it 处插入 2 个 3 ,注意这个语句执行完之后 it 就失效了
vector <int> u(3,1);
u.insert(u.begin(),v.begin(),v.end());//在 u.begin() 处插入 [v.begin(),v.end()) 这个范围内的元素

1.10 operator []

​ 这个不用说了吧都懂。

1.11 pop_back

​ 设 v 为一个 vector ,则 v.pop_back() 表示弹出 v 的最后一个元素。

1.12 push_back

​ 设 v 为一个 vector ,则 v.push_back(x) 表示在 v 的最后插入一个元素 x 。

1.13 size

​ 设 v 为一个 vector ,则 v.size() 返回当前 v 中的元素个数。

1.14 resize

1.15 relational operators

​ 判断两个 vector 是否相等的时候,先比较 size(),然后再逐位比较。

​ 设 a,b 为两个 vector,判断 a<b 是否成立时,按照字典序判定,也就是从 (a[0],b[0]),(a[1],b[1]),... 开始不断比较。

​ 其他的四种比较符直接用以上两种来生成。

2. set

从这里开始,和 vector 有相同意义的函数的解释就省略了。

​ 接下来默认定义 set <int> S

​ 单次操作的复杂度基本都是 \(O(\log Size)\) 的。

​ 它的初始化类似于 vector 。

2.1 begin

2.2 clear

2.3 count

S.count(x) 表示求 S 中 x 元素的出现次数。由于 set 中各个元素互不相同,所以只会返回 0 或 1 。

​ 单次时间复杂度 \(O(\log Size)\) 。

​ 1000000 次 count 的用时大约在 0.3 秒到 1 秒左右,取决于电脑的运行效率。

2.4 empty

2.5 end

2.6 erase

​ 用于删除元素。

S.erase(it);// 删除 set 迭代器 it 指向的元素。删除完之后这个迭代器就失效了。
S.erase(x);// 删除元素 x
S.erase(it1,it2);// 删除 [it1,it2) 的所有元素
S.erase(it,S.end());// 上一种用法的一个实例

2.7 find

S.find(x) 返回一个迭代器,这个迭代器指向的元素值为 x 。

2.8 insert

S.insert(x) 表示在 S 中插入元素 x ,并返回一个 pair <set <int> :: iterator,bool> ,第一个元素表示插入元素 x 之后 x 的迭代器(如果原本就有 x 就返回原来的 x 的迭代器),第二个元素表示这次插入是否有效,如果 x 原先不在 S 中,那么返回 true,否则返回 false。

S.insert(it1,it2) 表示在 S 中插入 [it1,it2) 的所有元素。

2.9 lower_bound

S.lower_bound(x) 返回 S 中指向 大于等于 x 的最小元素 的迭代器。

2.10 upper_bound

S.upper_bound(x) 返回 S 中指向 大于 x 的最小元素 的迭代器。

2.11 size

2.12 multiset

​ multiset 是可重集,也就是说容器内可以有多个相同元素。

​ 大部分用法和 set 一样,这里只讲较为不同的。

​ 接下来默认定义 multiset <int> S

​ 注意 multiset 的常数比 set 大若干倍。

2.12.1 count

S.count(x) 返回 S 中元素 x 的个数。

​ 这里单次 count 的时间复杂度大约是 \(O(\log Size + S.count(x))\) 的。

​ 实测常数不大,设 n = 10000,则在 S 中 insert n 个 1,再 insert 2...n 各一个,再进行 n 次 S.count(1) 的用时大约在一秒左右(不开 O2),取决于电脑的运行效率。

​ n=10000 时,实测用时 0.6s 的电脑,在 n = 100000 时大约要 200s,在 n = 1000 时大约要 0.02s 。

2.12.2 equal_range

S.equal_range(x) 返回类型为 pair <multiset <int> :: iterator, multiset <int> :: iterator> 第一个元素和第二个元素分别表示 S 中值为 x 的第一个迭代器位置和最后一个迭代器位置的后一个位置。

2.12.3 erase

​ 注意一下 S.erase(x) 的作用是删除 S 中所有等于 x 的元素。

​ 所以在要删除一个 x 的时候得写成 S.erase(S.find(x)) ,这样就只会删掉一个迭代器所指向的值。

2.13 relational operators

set 和 multiset 以及 vector 类似。 唯一的区别是 set 的顺序是从小到大比较,vector 是按照下标顺序比较。

3. map

​ map 常用于离散化,可以当做一个下标可以是任意类型、任意值的数组用。

​ 单次操作的时间复杂度基本都是 \(O(\log Size)\) 。

​ map 类型的迭代器比较特殊,例如 map <long long,int> :: iterator 指向的就是一个 pair <long long,int> ,表示元素 first 所对应的值为 second。

​ map 的初始化也类似于 vector 。

​ 接下来默认定义了 map <int,int> Map

3.1 begin

3.2 clear

3.3 count

Map.count(x) 表示元素 x 的是否被插入过。

3.4 empty

3.5 end

3.6 equal_range

3.7 erase

​ 和 set 中 erase 的用法是一样的。

3.8 find

​ 和 set 中 find 的用法是一样的。

3.9 insert

​ map 的 insert 和 set 的 insert 略有不同。

​ map 中 insert 的东西是个 pair,但是 set 中是个元素。

​ 其他都是一样的。

3.10 lower_bound

3.11 upper_bound

3.12 operator []

​ 这个有用的重载符大概就是用 map 而不用 set 的动机吧!

Map[x] 返回 Map 中 first 是 x 的那个 pair 的 second 的引用。

​ 例如:

map <int,int> Map;
Map[233]++;
Map[-999]+=Map[233];
Map[233]+=Map[-999];
Map[123000000]=Map[-999]+Map[233];
cout<<Map[-999]<<" "<<Map[123000000]<<" "<<Map[233]<<endl;

​ 输出结果为

1 3 2

3.13 size

3.14 relational operators

4. unordered_map

​ 需要 c++11 或更新的编译器才可以使用。

​ 它是一个 Hash 表。

​ map 的弱化版,由于实现原理不同,所以 map 的很多功能他没有,但是它有它唯一的优势

——单次操作时间复杂度 \(O(1)\) 。

​ 但是实测运行效率只和 map 差几倍而已。

​ 手写 Hash 表往往能比它快 6~10 倍。

​ 所以这里不展开介绍。

5. priority_queue

​ 优先队列,堆。

​ 完全可以使用 set 代替。不同于 set ,它的功能比较弱,不支持删除等一系列操作,单次操作的时间复杂度还是一样的 \(O(\log Size)\),那么它的用处是什么?

​ 它常数小。大约是 set 的 0.5 倍。

​ 注意优先队列 没有 迭代器。

​ 系统默认的优先队列是大根堆。

​ 初始化还是和 vector 差不多的。

​ 接下来默认定义 priority_queue <int> Q

5.1 定义

定义一个 int 类型的大根堆:priority_queue <int> Q1

定义一个 char 类型的小根堆: priority_queue <char,vector <char>,greater <char> >Q2

重载比较运算符:

struct cmp{
bool operator () (int a,int b){
//......
}
};
priority_queue <int,vector <int>,cmp> Q3;

5.2 empty

5.3 pop

Q.pop() 表示弹出堆顶元素。

5.4 push

Q.push(x) 表示将元素 x 加入 Q 。

5.5 size

5.6 top

Q.top() 会返回 Q 的第一个元素。

6. stack

​ 它连 operator [] 都没有,不如手写。

7. queue

它连 operator [] 都没有,不如手写。

8. deque

​ 它叫做双端队列。

​ 在常数要求严格的情况下,deque 会非常好用。

​ deque 就像一个升级版 vector ,它在支持从后面插入的同时支持从前端插入。而且它还重载了 operator [] 。

​ 它的初始化是和 vector 差不多的。

​ 它的单次操作复杂度也基本都是 \(O(1)\) 。

​ 它 迭代器。

​ 下面默认定义 deque <int> Q

8.1 begin

8.2 clear

8.3 empty

8.4 end

8.5 erase

8.6 front

Q.front() 会返回 Q 的第一个元素的引用。

8.7 insert

8.8 operator []

Q[x] 返回 Q 从前往后数的第 x+1 个元素的引用。

8.9 pop_back

8.10 pop_front

Q.pop_front() 表示弹出 Q 的第一个元素。

8.11 push_back

8.12 push_front

Q.push_front(x) 表示在 Q 的最前面插入元素 x 。

8.13 resize

8.14 size

8.15 relational operators

STL 贺习笔记的更多相关文章

  1. NET Core-学习笔记(三)

    这里将要和大家分享的是学习总结第三篇:首先感慨一下这周跟随netcore官网学习是遇到的一些问题: a.官网的英文版教程使用的部分nuget包和我当时安装的最新包版本不一致,所以没法按照教材上给出的列 ...

  2. NET Core-学习笔记(二)

    这里要分享的是接着上篇:NET Core-学习笔记(一)展开的继续学习core笔记,有不妥之处或者更好见解的地方希望各位朋友多多分享. 下面是本篇将要分享的学习步奏,对于刚学或者即将要学习的朋友做个相 ...

  3. Sass-学习笔记【进阶篇】

    特别说明: 没有sass基础请移步:[Sass-学习笔记[基础篇]]http://www.cnblogs.com/padding1015/articles/7056323.html 最底部附结构图(实 ...

  4. Sass-学习笔记【基础篇】

    最下边附结构图 在线编辑器网址如下:http://sassmeister.com/  注意编写的时候,符号千万别用了中文的:.:.....之类的,会报错,Sass也转换不成css. less和sass ...

  5. PHP-学习笔记-进阶

    PHP-学习笔记-进阶 PHP类和对象之定义类的方法 访问控制的关键字代表的意义为: public:公开的 protected:受保护的 private:私有的 我们可以这样定义方法: class C ...

  6. opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测

    opencv-学习笔记(6)图像梯度Sobel以及canny边缘检测 这章讲了 sobel算子 scharr算子 Laplacion拉普拉斯算子 图像深度问题 Canny检测 图像梯度 sobel算子 ...

  7. opencv-学习笔记(5)形态学转变

    opencv-学习笔记(4)形态学转变 本章讲了几种形态学操作 腐蚀erode 膨胀dilate 开运算MORPH_OPEN 闭运算MORPH_CLOSE 形态学梯度MORPH_GRADIENT 礼帽 ...

  8. opencv-学习笔记(4)-模糊

    opencv-学习笔记(4)-模糊 本章要点: 4种模糊方式 2d卷积 Cv2.filter2D(‘图像对象’,‘目标图像这里直接设为-1即可’,kernal,anchor(-1,-1)) 一般后一个 ...

  9. opencv-学习笔记(3)

    opencv-学习笔记(3) 这章讲了 图像加法 opencv测试效率 IPYTHON测试效率 图像加法 cv2.add() 要求,两图片必须大小类型相同 然后是图像混合cv2.addWeighted ...

随机推荐

  1. Node的安装和进程管理

    安装nvm git clone https://github.com/creationix/nvm.git source nvm/nvm.sh 安装node nvm install 6.14.4(版本 ...

  2. 属性的get、set

    以年龄为例,通过属性,控制年龄的输入范围. 静态调用非静态时,需要通过对象来调用. namespace ConsoleApplication1 { class Program { private in ...

  3. 深入了解SQL的四种连接&不然要命的!

    1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...

  4. PLsql快捷键

    plsql使用技巧 1.类SQL PLUS窗口:File->New->Command Window,这个类似于oracle的客户端工具sql plus,但比它好用多了. 2.设置关键字自动 ...

  5. Windows Server2012 R2 安装.NET Framework 3.5

    拿到手的虚拟机系统是Windows server 2012R2,本想着安装SQlserver2012轻轻松松,结果途中警告未安装.NET Framework 3.5.于是找了个.NET Framewo ...

  6. 通信传输利器Netty(Net is DotNetty)介绍

    (先埋怨一下微软大大)我们做NET开发,十分羡慕JAVA上能有NETTY, SPRING, STRUTS, DUBBO等等优秀框架,而我们NET就只有干瞪眼,哎,无赖之前生态圈没做好,恨铁不成钢啊.不 ...

  7. spring boot项目能启动打包失败

    如题,项目本地可以正常启动.但是用 mvn clean package打包就失败! 事件原因如下: 一.pom.xml少packing元素 <groupId>com.sanyi</g ...

  8. 防止html页面缓存

    1.增加如下头 <meta http-equiv="Expires" content="0"> <meta http-equiv=" ...

  9. vue项目中遇到的那些事。

    前言 有好几天没更新文章了.这段实际忙着做了一个vue的项目,从 19 天前开始,到今天刚好 20 天,独立完成. 做vue项目做这个项目一方面能为工作做一些准备,一方面也精进一下技术. 技术栈:vu ...

  10. 浏览器将URL变成一个屏幕上显示的网页的过程?

    前言 一个浏览器是怎么工作的? 正文 URL变网页过程: 1.浏览器通过http或https协议,向服务端请求页面 2.将请求过来的HEML代码通过解析,构建DOM树 3.计算DOM树上的CSS属性 ...