马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
在算法比赛中,读入速率和输出速率不绝是卡常的紧张本领。也有不少人履历过被标题卡 cin 的情况。本日我给各人先容一下算法比赛中常用的读写方法及其优化。
声明:大部门情况下,只用读入优化就行。对于输出量大的标题再思量利用输出优化。
一、scanf/printf
这两个函数泉源于传统的 C,在 <stdio.h> 和 <cstdio>(仅 C++)中。利用方法:scanf("%占位符",&var); printf("%占位符\n",var);。如许比传统的 cin/cout 快,但由于誊写复杂而很少被人接纳。
scanf/printf 用法参考文章:详解c++中scanf和printf用法
二、cin/cout 优化
cin 和 cout是 C++ 的尺度输入输出流,在 <iostream> 头文件中,利用方法也非常简朴:cin>>var; cout<<var<<endl; 以是深受人们的喜欢。
在时间要求不高的标题中,用它们既省事,又可以让代码更雅观。
缺点:cin/cout 在不加优化的情况下速率慢于 scanf 和 printf。
缘故原由:C++ 为了和 C 保持同步、在混用 printf&scanf 和 cin&cout时的时间不发生紊乱,将它的输入/输出流绑到了一起。
办理方案:可以手动关闭同步,从而进步 cin 和 cout 的服从。std::ios::sync_with_stdio(false); 同时,还可以通过std::cin.tie(nullptr); 来清除 cin 和 cout之间的绑定,进一步减轻 cin 的负担。
cin/cout 用法:C++ 底子的输入输出先容:把握cin与cout的奥秘
三、endl 优化
有一个被人忽略的“大杀手”:endl。这一个语句和 \n 的效果类似,但更方便誊写,因此被人们广泛接纳。实在它的速率也特殊慢。大概会导致某些标题超时。
缘故原由:endl 输出时会清空缓冲区,这是为了让用户能实时看到输出,但会拖慢速率。而且由于它自己的功能界说,很难举行优化。
办理方案:打不外就不消呗 对于输出量大且须要换行的标题,利用 endl 有超时的风险,发起利用 cout<<'\n'。(平常刷题也发起用 \n,比力保险)
在实测中,C++14 的版本下,cin/cout 优化 + endl 优化的速率已经远快于 scanf/printf,发起在新评测机上利用上面两种方法优化。
- #include<iostream>
- using namespace std;
- int a[105];
- int main(){
-
-
- ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
- int n;
- cin>>n;
- for(int i=1;i<=n;i++){
-
-
- cin>>a[i];
- }
- for(int i=1;i<=n;i++){
-
-
- cout<<"a["<<i<<"]="<<a[i]<<"\n";
- }
- return 0;
- }
复制代码 四、传统快读、快写
原理:单个字符的输入输出速率要比读入数字快,因此我们以字符的情势先读入,然后处置处罚盘算转为数字,再用字符输出。
关于 isdigit()
在判定某个字符是不是整数时用的 isdigit() 函数,在差别编译器上的速率不一样。
在 这篇文章 中的测试效果:自己写比 VS 中的 isdigit() 快,但比 g++ 中的 isdigit() 慢。而且 g++ 中的 isdigit() 比 VS 中的 isdigit() 更快。
这篇文章 给我们展示了 Linux 内核中该函数王者级别的实现,各人可以学习。
自己写的话:
- #define my_isdigit(c) ( (c)>='0'&&(c)<='9' ) // C语言
- inline bool my_isdigit(char c){
-
- return (c>='0'&&c<='9'); } // C++
复制代码 快读
原理是先用单个字符读入全部零散的数字,再拼起来。拼数和判定字符见 这篇文章。
- template<typename T>
- inline void read(T &x){
-
-
- T w=1; x=0;
- char c=getchar();
- while(!isdigit(c)){
-
- if(c=='-'){
-
- w=-1;} c=getchar();}
- while(isdigit(c)){
-
- x=x*10+(c-'0'); c=getchar();}
- x=x*w;
- }
复制代码 快写
原理是把原来完备的数字拆成一个个字符输出。用递归的常数会略大,可以用模仿栈的方法时限。
递归代码:
- template<typename T>
- inline void write(T x){
-
-
- if(x<0){
-
- putchar('-'); x=-x;}
- if(x>=10){
-
- write(x/10);}
- write(x%10+'0'); //+'0'是为了让数字类型的x%10变成字符输出
- }
复制代码 模仿栈代码:(不能用模板了,要自己指定范例)
- inline void write(int x){
-
-
- static int st[35] = {
-
- 0};</
复制代码 |