作为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的更多相关文章

  1. nyoj--55--懒省事的小明(STL优先队列)

    懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述       小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分 ...

  2. POJOの説明

    参考URL: https://baike.baidu.com/item/POJO/3311958?fr=aladdin https://wenku.baidu.com/view/eba89bbcf12 ...

  3. 【説明する】hash

    首先对于判重,我们能想到的方法有什么呢? 1)bool数组 2)set(集) 数组与集合的优缺点: 1.因为集合是对数组做的封装,所以,数组永远比任何一个集合要快. 2.数组声明了它容纳的元素的类型, ...

  4. 【説明する】KMP

    KMP是一个困扰我很久的算法,听老师或者是学姐讲了差不多有4次了,但是还是搞不太懂,今天终于,终于,终于搞懂了! ——2017-10-29 Vanora 首先推荐一下KMP详解——July 读罢之后内 ...

  5. 【説明する】DS

    其实就是数据结构课后题整理....只会一个是什么鬼 染色问题: 线段树? 功能太强大了! 我们并不需要那么多的功能 运用并查集!!! 将相同的并为一段 BZOJ 2375(讲真我没找到这个题在哪里.. ...

  6. UbuntuでPostgreSQLをインストールからリモートアクセスまでの手順

    PostgreSQLサーバの立ち上げに少しハマりましたので.メモしておきます. OS: Ubuntu14.04 LTS インストール 最初はPostgreSQLをインストールします.普通にapt-ge ...

  7. VirtualBox 共享文件夾

    説明:host為window10,guest為centos7 一.安装VBoxLinuxAdditions 1. 在guest上挂载virtualbox安装目录下的VBoxGuestAdditions ...

  8. Ruby中字符串与正则表达式的问题

    Ruby的正则表达式为Regexp类的对象 主要的元语言字符 記号 意味 例 説明 ^ 行頭 /^abc/ abcで始まる行 $ 行末 /abc$/ abcで終わる行 . 任意の1文字 /a.b/ a ...

  9. WebMidiLink

    g200kg > WebMidiLink > 1.Introduction WebMidiLink 2012/06/26 1.Introduction « Prev 1.Introduct ...

随机推荐

  1. VMware 虚拟化编程(3) —VMware vSphere Web Service API 解析

    目录 目录 前文列表 VMware vSphere Web Services API VMware vSphere Web Services SDK vSphere WS API 中的托管对象 Man ...

  2. Jmeter之HTTP请求图片上传功能

    在现在很多功能都存在图片上传,所以简单说明一下使用jmeter进行图片上传. 界面显示并说明 添加一个HTTP请求的取样器 1.获取上传图片的接口,配置路径和参数 2.在HTTP请求中,Impleme ...

  3. Python高效率遍历文件夹寻找重复文件

    前言 为什么要写这篇文章呢...主要还是业务中有个需求,遍历一个将近200w数据的文件夹,大部分还都是视频文件那种,但是这玩意用的次数还不多,做文件夹index也不是很ok,所以写了一个脚本来处理这个 ...

  4. GMSSL在Window下的编译

    因为工作需要用到SM2算法加解密,网络上找一圈,没有合用的,还被骗了一堆积分. 无奈只得自行编译,从GITHUB的GMSSL下载到最新的SSL库,VS2012下编译踩了不少坑,记录一下 GITHUB链 ...

  5. SQLServer中的top、MySql中的limit、Oracle中的rownum

    (1)在SQL Server中,我们使用 select top N * from tablename来查询tablename表中前N条记录. (2)在MySQL中,我们使用select * from ...

  6. LeetCode——28. Implement strStr()

    题目: class Solution { public: int strStr(string haystack, string needle) { if(needle.empty()){ return ...

  7. 怎么用 pytorch 查看 GPU 信息

    如果你用的 Keras 或者 TensorFlow, 请移步 怎么查看keras 或者 tensorflow 正在使用的GPU In [1]: import torch In [2]: torch.c ...

  8. git多账号配置,同时使用多个代码托管平台

    git多账号配置,同时使用多个代码托管平台:https://blog.csdn.net/pinnuli/article/details/81293071

  9. K-th Number Poj - 2104 主席树

    K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...

  10. C++ 函数返回对象时并没有调用拷贝构造函数

    #include <iostream> #include <vector> #include <string.h> using namespace std; cla ...