【説明する】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 ...
随机推荐
- HttpClient实现通过url下载文件
其实就是通过浏览器url,点击就会下载文件. 这里是从代码层面上,对文件进行下载. package main.java.com.abp.util; import org.apache.http.*; ...
- nginx-->基本使用
Nginx基本使用 一.下载 http://nginx.org/en/download.html 二.解压文件 在当前文件夹下通过终端就可以操作nginx nginx -v 三.配置详解 #use ...
- python+selenium的WebElement对象操作
webelement对象操作 webelement对象是selenium中所有元素的父类,也就是webelement对象拥有的方法,其它元素对象都会有: 只是不同的对象在调用特定方法时,效果是不一样的 ...
- SpringMvc参数绑定出现乱码解决方法
在SpringMvc参数绑定过程中出现乱码的解决方法 1.post参数乱码的解决方法 在web.xml中添加过滤器 <!-- 过滤器 处理post乱码 --> <filter> ...
- 【Python—字典的用法】创建字典的3种方法
#创建一个空字典 empty_dict = dict() print(empty_dict) #用**kwargs可变参数传入关键字创建字典 a = dict(one=1,two=2,three=3) ...
- MySQL-第十三篇使用ResultSetMetaData分析结果集
1.Result里面包含了一个getMetaData()方法,该方法返回该ResultSet对应的ResultSetMetaData对象. 2.ResultSetMetaData包含的方法: 1> ...
- JavaScript 的继承与多态
本文先对es6发布之前javascript各种继承实现方式进行深入的分析比较,然后再介绍es6中对类继承的支持以及优缺点讨论.最后介绍了javascript面向对象编程中很少被涉及的“多态”,并提供了 ...
- 【洛谷p2239】螺旋矩阵
关于题前废话: 这道题的数据范围过于强大了qwq,显然如果我们开一个30000*30000的二维数组来模拟,显然首先就开不下这么大的数组,然后暴力搜索的话也会爆掉,所以直接模拟显然是一个不正确的选择( ...
- csrf的中间件
csrf的中间件 源码简略分析: def process_request(self, request): # 从cookies中获取csrf_token csrf_token = self._get_ ...
- P3064 [USACO12DEC]伊斯坦布尔的帮派 (模拟)
题目传送门 题意: 一片草地,每次可以只可以让一种牛占领,问你怎样安排牛的次序 最后剩下的是1号牛,并且输出其数量 思路: 看到n到100 ,所以可以(n^3)暴力,第一重遍历次序,第二枚举是哪只牛 ...