STL库的链接
cin cout 读写慢的优化
#include <iostream>
using namespace std;
int main(){
ios::sync_with_stdio(false);
ios_bast::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
关闭同步流,同时避免使用printf()\scanf()\getchar()等
关闭后比printf()和scanf()快
vector<>容器(注 :不是向量)
头文件#include<vector>
<>里填数组变量类型
vector类自带数组功能,含有多种对数组操作的函数模板
是栈、队列、堆的体现形式之一
学习链接:
(4条消息) STL - vector_道标 · 年的博客-CSDN博客
unique()函数
存在于algorithm中
用来将非重复元素移动至数组前面,返回指向最后一位非重复元素后面的地址(指针或迭代器)
链接:
(7条消息) unique 函数 详解_生于忧患,死于安乐2017的博客-CSDN博客_unique函数
string 变量
auto 变量(支持C++11以上版本)
自动匹配值的类型 方便对构造类函数的返回值或自定义类型的返回值
自定义中的运算符重载操作
类型名 operator <类型名+变量>{函数体}
#include<vector>
struct Range
{
int left,right;
bool operator< (const Range &W)const //<运算符重载
{
return right < W.right ;
}
};
第一个const 是为了不改动W(即去比较的参数)第二个const 是为了不改变自身的right
pair类比较时默认先比较第一个元素,若相等在比较第二个元素
若要先比较第二个元素,可以用操作符重载
什么是迭代器(iterator)
迭代器(iterator)是一种可以遍历容器元素的数据类型。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。C++更趋向于使用迭代器而不是数组下标操作,因为标准库为每一种标准容器(如vector、map和list等)定义了一种迭代器类型,而只有少数容器(如vector)支持数组下标操作访问容器元素。可以通过迭代器指向你想访问容器的元素地址,通过*x打印出元素值。这和我们所熟知的指针极其类似。
C++语言有迭代器,迭代器相对于指针而言功能更为丰富。
使用方法
#include<vector>
vector<int> :: iterator point; //变量实现方式
vector<int> :: iterator y(vector<int> &a) //函数实现方式
{
.......;
}
vector,是数组实现的,也就是说,只要知道数组的首地址,就能访问到后面的元素。所以,我们可以通过访问vector的迭代器来遍历vector容器元素。
List,是链表实现的,我们知道,链表的元素都存储在一段不是连续的地址空间中。我们需要通过next指针来访问下一个元素。那么,我们也可以通过访问list的迭代器来实现遍历list容器元素。
由此可见,迭代器和容器是密不可分的、紧密相连的的关系。不同的容器,它们的迭代器也是不同的,但是它们的迭代器功能是一样的。假如没有迭代器,由于vector和list容器的存储特点,你需要两种算法去实现遍历vector和list容器的功能,复杂且低效。有了迭代器,遍历容器的效率会大大提高。
不同容器的迭代器(iterator)的功能
vector 随机访问
deque 随机访问
list 双向
set / multiset 双向
map / multimap 双向
stack 不支持迭代器
queue 不支持迭代器
priority_queue 不支持迭代器
原文链接:https://blog.csdn.net/weixin_47700137/article/details/119251703
insert()函数
//用法1:在指定位置it前“插入”值为val的元素,返回指向这个元素的迭代器,
iterator insert( iterator it, const TYPE &val );
//用法2:在指定位置it前“插入”num个值为val的元素
void insert( iterator it, size_type num, const TYPE &val );
//用法3:在指定位置it前“插入”区间[start, end)的所有元素.
void insert( iterator it, input_iterator start, input_iterator end );
取自于qingshan3537转载的文章
(4条消息) C++容器的insert()函数三种用法_qingshan3537的博客-CSDN博客_c++ insert
关于卡常(针对不开O2)
1. int 改为 register int
register 表示使用cpu内部寄存器(是有限存储空间的高速储存部件)的变量,存到寄存器里能加加快读写速率
2.循环的 i ++ 改为 ++ i
因为++ i是先储存后计算
3.在函数类型前面加上inline,可以将函数指定为内联函数,这样可以解决一些反复调用的函数大量消耗栈空间的问题。
注 :对于递归函数(快排,归并等)inline 不适用
4.快读、快写
首先是关闭流同步的cin cout 比 printf 和 scanf 快
其次可以使用快读快写模板
快读 (循环):
template <typename T>
void read(T &x) {
x = 0;
int f = 1;
char ch = getchar();
while(!isdigit(ch)) { //isdigit在<cctype>中
if (ch == '-') {
f = -1;
}
ch = getchar();
}
while(isdigit(ch)) {
x = x * 10 + (ch - 48);
ch = getchar();
}
x *= f;
return;
}
快写(递归):
template <typename T>
void write(T x) {
if(x < 0) {
putchar('-');
x = -x;
}
if(x > 9) {
write(x / 10);
}
putchar(x % 10 + '0');
return;
}
使用方法和函数调用相同
5.位运算比一般非逻辑快
位运算的应用:
1)代替模运算
17 % 2 可写成 17 & 1,45 % 4 可写成 45 & 3, 986 % 16 可写成 986 & 15。
2)快速幂
快速幂模板:
int qk_pow(int x, int n){
if(n == 0) {
return 1;
}
int t = 1;
while(n) {
if(n & 1) { //用&代替%
t *= x;
}
n >>= 1; //用>>代替*
x *= x;
}
return t;
}
3)Swap函数
void Swap(int &a, int &b) {
a ^= b ^= a ^= b;
return;
}
6.使用三目运算符
return a < b ?a : b;
在数据庞大的情况下,使用三目运算符比使用if else或者switch case 要快不少
7.#pragma 指令
经常提到 O 2 \tt O2O2 这一说法,它的实现为:
#pragma GCC optimize(2)
当然还有 O 1 、 O 3 、 O s \tt O1、O3、OsO1、O3、Os。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC optimize(s)
还有一堆:
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
重点:开个O2就行了,欲速则不达。(指令集开多了会有负面作用)
8.IO优化:
namespace IO
{
char _p[15],p[5000005],buf[100005],*l=buf,*r=buf;
int lp;
inline char gc()
{return l==r&&(r=(l=buf)+fread(buf,1,100005,stdin),l==r)?EOF:*l++;}
inline void read(int &k)
{
char ch;while(ch=gc(),ch<'0'||ch>'9');k=ch-'0';
while(ch=gc(),ch>='0'&&ch<='9') k=k*10+ch-'0';
}
inline int readstr(char a[])
{
char ch;int len=0;
while(ch=gc(),ch<'a'||ch>'z');a[len++]=ch;
while(ch=gc(),ch>='a'&&ch<='z') a[len++]=ch;
return len;
}
inline void print(int x)
{
if(!x) p[++lp]='0',p[++lp]='\n';
else
{
int len=0;
while(x) _p[++len]=x%10+48,x/=10;
for(;len;--len) p[++lp]=_p[len];
p[++lp]='\n';
}
}
}
using namespace IO;
...
int main()
{
...
fwrite(p+1,lp,1,stdout);
return 0;
}
有氧优化(贴在代码开头)
#pragma GCC optimize("fast-math","unroll-loops","no-stack-protector")
#pragma GCC diagnostic error "-funsafe-loop-optimizations"
#pragma GCC diagnostic error "-fcse-skip-blocks"
#pragma GCC diagnostic error "-fwhole-program"
#pragma GCC diagnostic error "-std=c++14"
#pragma GCC target("sse3","sse2","sse")
#pragma GCC optimize("Ofast")
8.少用bool 类型变量比int 慢
————————————————
版权声明:本文为CSDN博主「_Alexander_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huangzihaoal/article/details/110182241
————————————————
版权声明:本文为CSDN博主「sight_720」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sight_720/article/details/122919247
有关O0 \ O1 \ O2 \ O3 优化(gcc 编译器)
O0优化
#pragma GCC optimize(0)
1、把变量分配到寄存器。
2、分析循环的会出现的各种情况,只保留一个退出循环的分支。
3、将没有用的代码删掉。
4、简化表达式和声明。
5、将用inline声明的内联函数变为函数调用。
O1优化
#pragma GCC optimize(1)
包含O0的各种优化功能,并增加了:
1、在变量赋值时,将数值直接赋给变量而不是给出变量的地址。
2、去掉没有用的变量和表达式。
3、去掉通用的表达式。
O2优化
#pragma GCC optimize(2)
包含O1的各种优化功能,并增加了:
1、去掉全局通用的子表达式。
2、去掉全局没有用的分配变量和表达式。
3、化解循环。
当只用-O选项时优化器自动进行-O2优化。
O3优化
#pragma GCC optimize(3)
包含O2的各种优化功能,并增加了:
1、去掉未调用的函数。
2、简化返回值未使用的函数。
3、将小函数进行内嵌调用。
4、对被调用的函数声明进行重新排序,以便被优化的调用方能够找到该函数。
5、完成文件级优化。
原文链接:https://blog.csdn.net/weixin_62264287/article/details/124196394
详细内部优化细节链接:
(7条消息) gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化_沈二月的博客-CSDN博客_gcc o2 o3
for(char c :a) C++11中遍历字符串的循环写法
1)这是C++11中新增的一种循环写法,对数组(或容器类,如vector和array)的每个元素执行相同的操作,此外string类也支持这种对字符的遍历循环操作。
如:
double prices[5] = {4.99,5.99,6.99,7.99,8.99};
for(double x:prices)
cout << x << endl;
其中,x最初表示数组prices的第一个元素,显示第一个元素后,不断执行循环,而x依次表示数组的其他元素。
当然,对于vector的遍历可以使用
for(vector<int> item : d){}
为了便利,还可以用
for(auto item : d )
同样 auto自动匹配类型也只适用于C++11
链接:
(7条消息) for (char c : s)这种循环方式的使用_wuxiecsdn的博客-CSDN博客
目前只收集一些C++11的小知识点,比较零碎,等再攒购一些会出合集,更有体系一些,还会在后续出有关STL数据库的模板类零碎知识点,分类更加明确