C++输入、输出优化模板整理
来源:互联网 发布:淘宝店铺搜索排名 编辑:程序博客网 时间:2024/05/21 07:00
前言
对于在信息学竞赛中逐渐深入学习的C++选手们,会发现有些题目的输入输出量特别大,有时可能一道题读入完你就TLE了。那么怎么办呢?少用cin或者cout,因为如果你对cin或者cout没有进行一些优化的话,它会跑的很慢,所以你如果不会输入输出优化的话,那就乖乖用scanf吧,这样会相对快一点。
但是呢,scanf速度还是不够快,那怎么办呢?那就用输入输出优化吧!
前置知识
getchar是读入函数的一种。它从标准输入里读取下一个字符,相当于getc(stdin)。返回类型为int型,为用户输入的ASCII码,出错返回-1
引用自 百度百科·getchar (计算机语言函数)
看了度娘上的定义,你大概知道getchar()这个函数的定义了吧。然后呢,度娘里没说,这个getchar()还是很快的呢,与它对应的还有一个putchar(),于是呢我们就可以用它来进行输入输出优化啦
(头文件是cstdio)
isdigit是计算机C(C++)语言中的一个函数,主要用于检查参数是否为十进制数字字符。用于判断字符c是否为数字,当c为数字0~9时,返回非零值,否则返回零。 可以用一个字符数组循环判断每一项是否为数字。
嗯,这个isdigit()能判断一个字符是不是数字,好像很有用呢,那就当一个前置知识吧
(头文件是cctype)
输入输出优化的简单版
void read(int&x)//只能读入非负整数{ char cu=getchar();x=0;//x置0,防止x有初始值 while(!isdigit(cu))cu=getchar(); while(isdigit(cu))x=x*10+cu-'0',cu=getchar();}void read(int&x)//能读入正、负整数和0{ char cu=getchar();x=0; bool fla=0;//记录这个数是不是负数 while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();} while(isdigit(cu))x=x*10+cu-'0',cu=getchar(); if(fla)x=-x; }//以上2个函数的用法为:对一个整型a,read(a)即可void print(int x)//只能输出非负整数{ if(x>=10)print(x/10); putchar(x%10+'0');}void print(int x)//能输出正、负整数和0{ if(x<0)x=-x,putchar('\n'); if(x>=10)print(x/10); putchar(x%10+'0');}//以上2个函数的用法为:对一个整型a,print(a)即可
这样你就会发现,你的输入输出快乐很多,如果算法相同,输入输出量较大,速度优势会比较明显呢。
嗯,好,如果你看懂了上面的代码,那我就贴一波我自己用的代码(加了一波优化,不要问我什么意思,有些关键词如果不知道就自己去查吧)
template <typename T> inline void read(T&x){ char cu=getchar();x=0;bool fla=0; while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();} while(isdigit(cu))x=x*10+cu-'0',cu=getchar(); if(fla)x=-x; }template <typename T> void printe(const T x){ if(x>=10)printe(x/10); putchar(x%10+'0');}template <typename T> inline void print(const T x){ if(x<0)putchar('-'),printe(-x); else printe(x);}
温馨提醒
使用这份输入输出代码时请不要用它来读入小数、字符串之类的(因为这份代码是读整型的啊),还有如果你不得已还要用其它的东西,那请你谨慎使用,因为这份读优可能会吃掉你的下个字符(有可能是换行符)。当然你要是完全理解了,当然可以使用啦
输入输出优化的升级组件
哇~用了读优之后程序读入的飞快呢~对吧。
然后呢,我想告诉你的是,你还是会在输入速度上被碾压,为什么呢?因为还可以继续优化哦
请看getchar()的函数内容
int getchar(void){ static char buf[BUFSIZ]; static char* bb=buf; static int n=0; if(n==0) { n=read(0,buf,BUFSIZ); bb=buf; } return(--n>=0)?(unsigned char)*bb++:EOF;}
是不是有优化的空间呢,用fread,一次多读一些东西就快了,自己实现,自然会比自带的快呢(C++自带的会因为考虑一些安全问题而变慢)
具体怎么优化呢?看下面
namespace fast_IO{ const int IN_LEN=10000000,OUT_LEN=10000000; char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf; char *lastin=ibuf+IN_LEN; const char *lastout=ibuf+OUT_LEN-1; inline char getchar_() { if(ih==lastin)lastin=ibuf+fread(ibuf,1,IN_LEN,stdin),ih=ibuf; return (*ih++); } inline void putchar_(const char x) { if(ih==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf; *oh++=x; } inline void flush(){fwrite(obuf, 1, oh - obuf, stdout);}}using namespace fast_IO;#define getchar() getchar_()#define putchar(x) putchar_((x))int main(){ return flush(),0;//别忘了这个flush哦,放在这里是不会出问题的,要是你没打那可就不能用这个优化了}
前面那一段要放在程序的最前面,然后还要说一件事,#define getchar() getchar_()、#define putchar(x) putchar_((x))最好在你自己调试的时候注释掉,或者你用文件输入输出(freopen),否则你会发现你的程序会一直显示等你输入
总结
在C++中,输入输出有很多优化,这只是一种,但又很有效。不过呢,要用的话最好要自己理解,否则可能会出问题,几个注意事项:
- namespace fast_IO 那一段要打在最前面
- read()、print()只能输入输出整数
- 用read()、print()的时候用其它输入输出方式(cin、cout、gets()、scanf、printf、puts())要谨慎使用,用namespace fast_IO的时候禁止使用其它输入输出方式
- 使用namespace fast_IO要注意内存问题,那里面有一个很大的char数组,小心MLE
最后贴出所有输入输出整合在一起的代码
#include<cstdio>#include<cctype>namespace fast_IO{ const int IN_LEN=10000000,OUT_LEN=10000000; char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf; char *lastin=ibuf+IN_LEN; const char *lastout=ibuf+OUT_LEN-1; inline char getchar_() { if(ih==lastin)lastin=ibuf+fread(ibuf,1,IN_LEN,stdin),ih=ibuf; return (*ih++); } inline void putchar_(const char x) { if(ih==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf; *oh++=x; } inline void flush(){fwrite(obuf, 1, oh - obuf, stdout);}}using namespace fast_IO;#define getchar() getchar_()#define putchar(x) putchar_((x))template <typename T> inline void read(T&x){ char cu=getchar();x=0;bool fla=0; while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();} while(isdigit(cu))x=x*10+cu-'0',cu=getchar(); if(fla)x=-x; }template <typename T> void printe(const T x){ if(x>=10)printe(x/10); putchar(x%10+'0');}template <typename T> inline void print(const T x){ if(x<0)putchar('-'),printe(-x); else printe(x);}int main(){ return flush(),0;}
大家学一下输入输出优化,能让自己的程序跑的更快哦
- C++输入、输出优化模板整理
- C程序设计语言整理笔记(七)输入与输出
- C++输入、输出优化
- {模板}C++输出优化
- 知识点整理----输入/输出函数
- C程序设计语言--输入/输出
- C --- 文件输入/输出
- C格式化输入/输出
- C++:输入与输出
- 【C】标准输入/输出
- C格式化输入、输出
- [C++]输入/输出流类库
- C输入与输出
- C 输入 & 输出
- C++ 读入优化与输出优化 模板
- 【SinGuLaRiTy-1009】 模板-读入优化 & 输出优化
- (整理)关于C语言中的输入和输出函数的一些运用
- mini2440串口的输入和输出整理
- JavaScript与Java之间AES加密解密
- Sublime 下配置Python程序交互式运行和单步调试
- URLClassLoader加载类的路径
- Centos7安装python3与python2并存
- unity官方内置网络unet的实例教程(八)
- C++输入、输出优化模板整理
- Linux中atme,ctime,mtime的区别
- 思路变换
- freemarker语法
- 使用hibernateTemplate执行add方法 出现Write operations are not allowed in read-only mode (FlushMode.MANUAL)
- ios文档网址
- NOIP2017普及组★跳房子
- freemarker配置
- [NOIP2017普及组]T2图书管理员(前导0)