【説明する】STL
作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的。
STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现。
所以今天要整理的东西就是STL!(orz 杨乐大神)
一.引入
STL(Standard Template Library),即标准模板库。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。
从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming),引入了诸多新的名词,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。
与OOP(object-oriented programming)中的多态(polymorphism)一样,泛型也是一种软件的复用技术。
从实现层次看,整个STL是以一种类型参数化(type parameterized)的方式实现的,这种方式基于一个在早先C++标准中没有出现的语言特性--模板(template)。
如果查阅任何一个版本的STL源代码,你就会发现,模板作为构成整个STL的基石是一件千真万确的事情。
除此之外,还有许多C++的新特性为STL的实现提供了方便。
STL 相当于一个工具箱,里面有 C++ 内置的函数与容器,可以直接拿来使用(这样就不用连工具都要自己造了)!
但这些我们暂且不深入谈,仅仅来了解她的大体,会使用她便可(反正深了我也不会hhhh)
二.分析?
运用头文件大部分都是
#include<algorithm>
用的时候只需要在头文件中包含进来即可
algorithm(算法) 完成特定功能
container(容器) 用于存储数据
iterator(迭代器) 访问容器中的内容[类似于指针]
三.我认为比较常用的STL:
1.Algorithm(算法)部分
1)
* min(x, y):取两者中的较小值
* max(x, y):取两者中的最大值
max+min函数(这个好像是在cmath也是有的吧,记不太清楚,有兴趣的可以手动Ctrl)
{
它们调用起来十分简单,只要满足 x,y 是相同类型,并且可以比较大小即可
必须是同种类型之间进行的比较!
(int与double不能够进行比较)
Eg:
int a = , b = , c = min(a, b); // c = 4
double x = 1.5, y = 3.5, z = max(x, y); // z = 3.5
}
2)
* swap(x, y):交换两者的值
swap函数
{
调用时只要满足 x,y 是相同类型即可
Eg:
int a = , b = ;
swap(a, b); // a = 4, b = 5
double x = -1.0, y = 2.5;
swap(x, y); // x = 2.5, y = -1.0
// !swap(a, x) 无法调用:类型不相同
}
3)
* sort(first, last):对于在 [first, last) 中的元素进行排序
* sort(first, last, comp):对于在 [first, last) 中的元素进行排序,其中 comp 为比较器
sort函数
{
默认是从小到大进行排序,可以修改为从大到小进行排序,如下:
int a[] = {, , , , }; sort(a, a+);// a = [1, 2, 3, 4, 5, ...] 普通排序 int cmp(int x, int y)
{
return x > y;
} // 比较器 sort(a, a+, cmp);// a = [5, 4, 3, 2, 1, ...] 从大到小排序
几点需要注意的地方:
排序的区间为[first, last),左闭右开;
如果需要排序A[1..5]中的数,则需要调用sort(A+1, A+6);
* 其实还可以自己定义比较器,作为排序的准则:例如,我们需要按照个位数来比较大小,则可以定义比较器为
int cmp(int x, int y)
{
return x % < y % ;
}
* 对于自己定义的结构体,可以定义自己的比较器来实现排序功能。
// 以 a 为第一关键字,b 为第二关键字进行排序
int cmp(Mystruct x, Mystruct y)
{
return x.a == y.a ? x.b < y.b : x.a < y.a;//三目运算符
}
}
4)
* lower_bound(first, last, element):
给定 [first, last)中的已经从小到大好排序的元素,找出最前的一个不比 element 要小的元素的位置
lower_bound函数
{
注意:element返回的是指针,并不是下标!!
它的作用就是:
找出最前的一个不比element要小的元素的位置
ps:若均大于element,则返回最开始的位置
(小) (后)
Eg:
void lower_bound_stl()
{
int a[] = {, , , , , , , };
sort(a, a+); // a = [1, 2, 2, 3, 3, 4, 4, 5] 已从小到大排好序
int p2 = lower_bound(a, a+, ) - a; // p2 = 1
// a中最前的不比 2 小的元素是: a[1] = 2
int p4 = lower_bound(a, a+, ) - a; // p4 = 5
// a中最前的不比 4 小的元素是: a[5] = 4
int p0 = lower_bound(a, a+, ) - a; // p0 = 0
// a中最前的不比 0 小的元素是: a[0] = 1
int p6 = lower_bound(a, a+, ) - a; // p6 = 8
// a中没有不比 6 小的元素,所以返回最后的一个位置 a[8]
// 注意:a[8] 中并没有值,是数组的最末端
cout << p2 << endl;
cout << p3 << endl;
cout << p0 << endl;
cout << p6 << endl;
}
}
5)
疑似扯远的感觉?
*unique()函数是一个去重函数
unique()函数
{
STL中unique的函数 unique的功能是去除相邻的重复元素(只保留一个),还有一个容易忽视的特性是它并不真正把重复的元素删除。
他是c++中的函数,所以头文件要加#include<iostream>,具体用法如下:
int num[]; unique(num,mun+n); /*
返回的是num去重后的尾地址,之所以说比不真正把重复的元素删除,其实是,该函数把重复的元素一到后面去了,然后依然保存到了原数组中,然后返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序
*/
}
6)
strchr()函数为字符串判断函数
strchr
{
char c[]; strchr(c,'.') //如果c字符串中含有 '.' 则返回 '.' 的位置指针,否则返回NULL;
此函数包含在头文件#include<cstring>中。
如果有两个或两个以上字符就返回第一个的地址。
}
/*--------------------啦啦啦~我是萌萌的分割线酱~---------------------*/
2.容器 (Container)部分
STL 中的容器被分配在不同的库中,用的时候只需要在头文件中包含对应的库即可
#include <vector> // 向量:用于存储连续的元素,类似数组
#include <set> // 集合
#include <queue> // 队列
#include <stack> // 栈
#include <map> // 映射:相当于一个坐标无限大的数组
#include <priority_queue> // 优先队列:类似于堆
#include <list> // 列表:类似于链表
接下来介绍几个在程序中常使用的容器啦啦啦~
1)
向量(vector)
用于存储连续的元素,类似数组;并且可以动态改变数组的大小(不必提前声明数组大小)
给出可爱的代码酱~
void vector_stl()
{
// vector 声明
vector<int> a; // 声明一个空的 vector
vector<int> b(, ); // 声明 vector 中有 5 个元素,并且初始值都为 0
// vector 访问
for(int i=; i<; i++) b[i] = i; // vector 中下标从 0 开始
// ! a[0] = 1; 非法操作: a 还是空的,没有第一个位置
// ! a[5] = 5; 非法操作: b 没有第六个位置
// vector 添加元素
for(int i=; i<; i++) a.push_back(i * i); // 在 a 最后增加一个元素
for(int i=; i<; i++) cout << a[i] << " "; // 输出 vector a
// 输出结果: 0 1 4 9 16
// vector 设定长度
vector<int> c;
c.resize(); // 设置 c 的大小为 5,下标 [0-4]
c[] = -; // c[4] 是可以被访问的
// vector 长度 (数组大小)
int len = c.size(); // len = 5
// vector 清空
c.clear(); // 清空 c 数组
// ! c[4] = -4; 非法操作:数组已经被清空,长度变为 0
}
2)
二元组(pair)
用于存储二元组 (x,y)(并且 x,y 类型可以不相同)
代码酱来也~
void pair_stl()
{
// pair 声明
pair<int, int> a; // 声明一个二元组a
pair<int, int> b(, ); // 声明一个二元组b, x=3, y=4 typedef pair<int, int> PI;
PI c(, ); // 声明一个二元组c // pair 访问
int x = c.first, y = c.second; // x = 5, y = 6
PI d = c; // 相同类型的二元组可以直接赋值
c = PI(, ); // 重新赋值二元组
d = make_pair(, ); // 另一种赋值方式 /*二元组 (pair)的一个优点是可以直接比较大小;它会先比较第
一关键字(x),再比较第二关键字(y)*/
PI arr[];
for(int i=; i<; i++) arr[i] = PI( - i, i * i);
sort(arr, arr+);
for(int i=; i<; i++)
cout << "First element:" << arr[i].first << " "
<< "Second element:" << arr[i].second << endl;
/* 通过二元组 (pair)可以把不同类型的元素给有机整合起来*/
typedef pair<int, PI> PII; // 定义三元组
PII p = PII(, PI(, )); cout << p.first << "," << p.second.first << ","
<< p.second.second << endl; typedef pair<string, int> People; // 定义(字符串,整数)二元组
People pa("Edward", );
People pb("Bob", );
if(pa > pb) swap(pa, pb); // 可以直接进行比较,以字符串为第一关键字,整数为第二关键字进行比较
cout << pa.first << ":" << pa.second << endl; }
3)
集合(set)
1.在集合 (set)中,可以像普通的集合一样,保存所有不同的数
set<int> S; // 定义一个整型类型的 set
for(int i=; i<; i++) S.insert(i*i); // 把 0-9 的平方数加入集合中
set<int>::iterator p; // iterator:迭代器,相当于一个指针
p = S.find(); // 指针 -- 找到 4 所在位置
cout << *p << endl; // 输出这个位置的值 -- 4
++p; // 指针后移
cout << *p << endl; // 输出后一个平方数的值 -- 9
/*
输出结果:
4
9
*/
2.在集合 (set)中,可以支持查找一个数的位置
p = S.find(); // 假如我们想要找一个集合中没有的数
cout << "Notice : (5 is not a square number) " << *p << endl;
cout << (p == S.end()) << endl;
// 就会返回一个特殊的指针:S.end() 结尾的指针
// C++ 中的容器都是左闭右开的:
// S.begin() 头指针 - 存放数据,S.end() 尾指针 - 不存放数据
/*
输出结果:
Notice : (5 is not a square number) 10
1
*/
3.在集合 (set)中,还有另一种方式查看一个数是否在集合中
for(int i=; i<; i++)
if(S.count(i)) cout << i << " is an element of S." << endl;
else cout << i << " is not an element of S." << endl;
// count(x),如果 x 存在则返回 1,不存在则返回 0
/*
输出结果:
0 is an element of S.
1 is an element of S.
2 is not an element of S.
3 is not an element of S.
4 is an element of S.
5 is not an element of S.
6 is not an element of S.
7 is not an element of S.
8 is not an element of S.
9 is an element of S.
*/
4.还有最后一点就是,在集合 (set)中,亦可以直接支持lower_bound 操作
p = S.lower_bound(); // 假如我们想要找一个集合中不小于 20 的数
cout << "The first element not lower than 20: " << *p << endl;
S.delete(p); // 删除一个数:使用指针的方式
p = S.lower_bound(); // 再次寻找
cout << "The first element not lower than 20: " << *p << endl;
p = S.lower_bound(); // 假如我们想要找一个集合中不小于 100 的数
cout << (p == S.end()) << endl; // 假如没有数比它大,则返回尾指针
/*
输出结果:
The first element not lower than 20: 25
The first element not lower than 20: 36
1
*/
3.迭代器 (Iterator)部分
这里的其实我也不是很清楚w
STL 中的迭代器相当于不同的容器的指针
vector<int>::iterator vi; // 定义迭代器,直接在后面加::iterator
vector<int> V; // 定义容器
for(int i=; i<; i++) V.push_back(i * - ); // 新增值
for(vi = V.begin(); vi != V.end(); ++vi) cout << *vi << " ";
cout << endl; // 按顺序输出容器中的值
// 特殊的迭代器:V.begin(), V.end()(左闭右开)
// 迭代器可以自增:往后挪一位
// 不同容器的迭代器存在着区别
输出结果:
1 4 7 10 13 16 19 22 25
// STL 中每个容器都有对应的迭代器 set<int> S; // 定义容器
set<int>::iterator p; // 定义迭代器 for(int i=; i<; i++) S.insert(i * i); // 插入平方数
p = S.begin(), ++p;
S.erase(p); // 第一种删除方式(迭代器) :删除第二个元素
S.erase(); // 第二种删除方式(值删除) :删除 49
cout << "The Sequence : ";
for(p = S.begin(); p != S.end() ; ++p) cout << *p << " ";
cout << endl; // 顺序输出
输出结果:
The Sequence : 0 4 9 16 25 36 64 81
End.
【説明する】STL的更多相关文章
- nyoj--55--懒省事的小明(STL优先队列)
懒省事的小明 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分 ...
- POJOの説明
参考URL: https://baike.baidu.com/item/POJO/3311958?fr=aladdin https://wenku.baidu.com/view/eba89bbcf12 ...
- 【説明する】hash
首先对于判重,我们能想到的方法有什么呢? 1)bool数组 2)set(集) 数组与集合的优缺点: 1.因为集合是对数组做的封装,所以,数组永远比任何一个集合要快. 2.数组声明了它容纳的元素的类型, ...
- 【説明する】KMP
KMP是一个困扰我很久的算法,听老师或者是学姐讲了差不多有4次了,但是还是搞不太懂,今天终于,终于,终于搞懂了! ——2017-10-29 Vanora 首先推荐一下KMP详解——July 读罢之后内 ...
- 【説明する】DS
其实就是数据结构课后题整理....只会一个是什么鬼 染色问题: 线段树? 功能太强大了! 我们并不需要那么多的功能 运用并查集!!! 将相同的并为一段 BZOJ 2375(讲真我没找到这个题在哪里.. ...
- UbuntuでPostgreSQLをインストールからリモートアクセスまでの手順
PostgreSQLサーバの立ち上げに少しハマりましたので.メモしておきます. OS: Ubuntu14.04 LTS インストール 最初はPostgreSQLをインストールします.普通にapt-ge ...
- VirtualBox 共享文件夾
説明:host為window10,guest為centos7 一.安装VBoxLinuxAdditions 1. 在guest上挂载virtualbox安装目录下的VBoxGuestAdditions ...
- Ruby中字符串与正则表达式的问题
Ruby的正则表达式为Regexp类的对象 主要的元语言字符 記号 意味 例 説明 ^ 行頭 /^abc/ abcで始まる行 $ 行末 /abc$/ abcで終わる行 . 任意の1文字 /a.b/ a ...
- WebMidiLink
g200kg > WebMidiLink > 1.Introduction WebMidiLink 2012/06/26 1.Introduction « Prev 1.Introduct ...
随机推荐
- Java ——对象 类 方法重载 构造方法 封装 内部类
本节重点思维导图 快捷键 生成代码:alt+shift+s 提取变量:alt+shift+L 快速复制行:alt+ctrl+向上或向下的箭头 删除行:ctrl+d 类:对同一种事物共同属性和行为的抽象 ...
- Arduino入门之前
胡乱乱的,就买了,这个 arduino的板子. 哎...本来明明是 学动漫的,然后 不小心就开始 做软件了,然后 越跑越偏...现在 开始 做 硬件开发了... 其实 还有 树莓派 可供选择,算了,不 ...
- Nginx https服务器证书安装步骤
本文档指导您如何在 Nginx 服务器中安装 SSL 证书. 说明: 本文档以证书名称 www.domain.com 为例. Nginx 版本以 nginx/1.16.0 为例. 当前服务器的操作系统 ...
- java实战应用:MyBatis实现单表的增删改
MyBatis 是支持普通 SQL查询.存储过程和高级映射的优秀持久层框架.MyBatis 消除了差点儿全部的JDBC代码和參数的手工设置以及结果集的检索.MyBatis 使用简单的 XML或注解用于 ...
- SQL在Oracle内部的具体处理流程
下图显示了SQL在Oracle内部处理的一般阶段:解析.优化.产生行源和执行.数据库可能会忽略某些步骤,这取决于具体的语句. ...
- C# http post请求帮助类
using System; using System.Collections.Specialized; using System.IO; using System.Net; using System. ...
- 【focus-lei 】微服务
随笔分类 - 微服务 .net core使用NLog+Elasticsearch记录日志 摘要:在微服务或分布式系统中,如果将日志作为文件输出,查看系统日志将非常不便:如果将日志保存到数据库中,又不能 ...
- C#设计模式:迭代器模式(Iterator Pattern)
一,什么是迭代器模式(Iterator Pattern) 提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴露该对象的内部表示 二,看下面例子: using System; using Sys ...
- JS对象总结
JS对象总结 复习: 1.1 JS中对象有三种:内置对象(数组Array对象.String字符串对象.RegExp正则表达式对象.Math对象). 宿主对象(JS脚本所在的运行环境,目前我们讲的脚 ...
- em、rpx和px的换算
rpx:对于小程序开发,所用的单位都是rpx,而不论哪个型号的手机,屏幕宽度都是750rpxrpx与px的转换,根据设计稿换算例如:设计稿750px宽度,ps上量出或者标出的宽度是多少,那么就定义多少 ...