对于在信息学竞赛中逐渐深入学习的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)
这样你就会发现,你的输入输出快乐很多,如果算法相同,输入输出量较大,速度优势会比较明显呢。 嗯,好,如果你看懂了上面的代码,那我就贴一波我自己用的代码(加了一波优化,不要问我什么意思,有些关键词如果不知道就自己去查吧)
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,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1; inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;} inline void putchar_(const char x){if(oh==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),否则你会发现你的程序会一直显示等你输入 update by 2019/1/2:其实还有个不用注释掉的方法就是在输入的最后输入Ctrl+z然后Enter就可以了
在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,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1; inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;} inline void putchar_(const char x){if(oh==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; }大家学一下输入输出优化,能让自己的程序跑的更快哦 update by 2019/1/2:对读优进行了部分压行和更新,之前的那份的fread部分有小bug
