算法竞赛中的STL
须知:本文是为普及/提高-的选手准备的,有些在OI中并没有什么用
ps:本蒟蒻第一次发日报,请大佬指教
pss:摘自HEU2020冬令营课件
目录
-
模板和类(重载运算符)
-
C++输入输出(I/O,file,string)
-
没了(雾)
==========================================================
模板——template
还记得void*吗?
void*可以通过强制类型转换成为任意指针类型。
template的作用其实差不多,但是功能更加强大!
概括地说,template就是用一个自定义的类型名作为一个万能的类型
我们以一个函数为例:
int sum(int a,int b){return a+b;}
显然这个函数只能求int类型的两数相加。
那么能不能让这个函数变得“万能”?
有了模板,答案是肯定的!
template<typename temp>
temp sum(temp a,temp b){return a+b;}
这样我们就可以用它计算各种类型两数相加了。
在这里我们定义了一个temp的类型,叫做模板参数。当然temp可以换成别的东西。
这样函数就可以自动识别传入的变量的类型,然后按照这个类型返回。
有了template,我们可以写出很多方便的函数。
stl的绝大部分函数都是带模板的。
例如algorithm里的min函数(头文件里的函数都好丑qwq)
我们也可以定义多个模板参数:
template<typename T1,typename T2>
我们可以通过模板定义一个结构体:
template<typename T>struct point{T x,y;};
这样定义的时候就可以用point<int>p来申请一个x和y都是int的point变量。
很像STL的容器对不对?实际上,STL的大部分容器都采用了模板技术。
我们还可以像函数参数的初始化那样初始化模板参数:
template<typename T=int>struct point{T x,y;};
定义的时候就可以用point<>p了,此时p.x和p.y都是int类型的。
我们还可以在模板参数中填int等类型!
这样就可以用arr<233> b来申请一个内置长度为233的数组的变量啦。
C++11的array就是利用它实现的。
typename可以用class替换,但是此处的class与下面要讲的class类不同!
类——class
类class是一种封装的数据结构,类似于结构体struct,但略有不同。
例如:
struct point{int x,y;};
对应的class是:
仅仅是加了一个public而已。
那么这个public有什么作用呢?
其实除了public,class中还有private和protect。
private表示函数或变量不能通过 变量.函数 进行访问,而只能在class中访问。
protect指函数或变量是受保护的。
以上在算法竞赛中基本用不到awa
用法的话可以看一下代码包里的bigint.h。
重载运算符——operator
重载运算符对于类和结构体都适用。
首先我们要知道带运算符的式子也是一个函数。
比如(int) a+b就可以看成一个返回值是int,两个参数分别是a和b的函数。
重载运算符就是给结构体定义一些这样的函数。
如果在类或结构体内部重载运算符则参数只有一个,是运算符左边的变量。
如果在结构体外重载则是两个参数,分别是左边和右边的变量。
其实这东西只要搞清楚参数和返回值就好办了。
还是这个结构体:
struct point{int x,y;};
在内部重载加号运算符就是
在外部重载则是
C++的输入输出
写在STL之前……(伪·STL)
C++I/O(in/out stream)
这个有什么好讲的呢……
首先你知道cin是什么吗?是函数吗?
当然不是,cin是istream类! 重载了”<<“和”>>”运算符。
你可以把类(class)理解为复杂的结构体。
众所周知,这东西很慢……
但是有提速方法!
对于cin来说,只要加上这一句就能显著加速:
ios::sync_with_stdio(false);
意思是关闭与stdio的同步,也就是说,你不能再混用cin和scanf了……
速度优化显然(10^6个整数的读入与输出):
(可还是不如scanf……)
对于cout来说,它的速度其实接近于printf; 拖慢其速度的主要因素是endl。
所以优化就是把endl换成’\n’。
C++I/O (file stream)
stream类也是支持文件操作的!
我们需要
#include<fstream>
ifstream fin(“输入文件名”);
ofstream fout(“输出文件名”);
…
fin.close();fout.close();
然后把cin、cout换成fin、fout即可。
这东西的优点是可以同时用cout、printf等进行屏幕输入输出,调试比较方便,还不会计入结果。
速度约等于取消同步的cin/cout。
可以多次调用fin.close()和fin.open(“in.txt”)来实现文件的反复读入。
甚至还有把两者结合到一块的fstream类:
fstream fs(“xxx.txt”);
实现了对文件的读入和输出!
即fs>>xx; fs<<“qwq”;
要注意的是写入时会清空原文件后再写入。
C++I/O (string stream)
“再恶心的读入也能用stringstream轻松解决!”——某dalao
#include<sstream> //……
定义:
stringstream ss(s);
s是要作为流内容的字符串,就是把s作为读入内容, 然后就可以ss>>n了。
不懂就看个例题吧。
题目描述:给你一个序列,求序列最大值。
输入描述:输入有多行,每行是一个序列,每个整数间用’,’隔开。
输出描述:对于每行的序列,输出最大值。
样例输入:
1,3,6,2,5
22,33,55,11
样例输出:
6
55
(这不是水题么……)
看你读入怎么打
有了stringstream,这题就变得很简单!
然而一个重要的问题是……
这东西常数十分大……
具体有多大呢? 还是刚才的题
比char数组慢了十几倍!
因此数据较大(>10^5)时不建议使用, sscanf()比这个稍快.
最后
关于STL
STL = Standard Template Library,标准模板库,惠普实验室开发的一系列软件的统称。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。
STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)六个部分。
简单地说,STL就是给你做好一些容器、函数等乱七八糟的东西,让你直接使用。
O2优化可以大大提升STL的速度,但有些场合不开。
全文完
撒花~qwq