C++随手记(比C丰富的内容,大部分在STL库中,支持C++11)转载知识点合集

STL教程:C++ STL快速入门(非常详细)

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数据库的模板类零碎知识点,分类更加明确 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

にマラゴ び

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值