输入输出优化集锦

team109

2019-08-11 22:10:29

Personal

Update: 2020.02.18 退役了还来更新。加了一个counter。在第六大块添加了一些。在第五大块加了一个`print2`。 2020.3.31 发现了两个神奇的东西,fputs和fgets。 # 目前在大改中 ![404](https://www.counter12.com/img-7YDa5W42Y8yZBBbY-7.gif) $ $ 这里主要针对输入。 $ $ $ $ ### 1.最快的,比大多数getchar党快不少: P.S.可以筛掉空格、回车、Tab ```cpp inline int read() { register char ch=getchar(); register int x=0; while(!(ch&16))ch=getchar(); while(ch&16)x=(x<<1)+(x<<3)+ch-48,ch=getchar(); return x; } inline int sread() { register char ch=getchar(); register int x=0; register bool b=0; while(!(ch&16)&&ch!='-')ch=getchar(); (ch=='-')&&(b=1,ch=getchar()); while(ch&16)x=(x<<1)+(x<<3)+ch-48,ch=getchar(); b&&(x=-x); return x; } ``` `fread`?不存在的。我太水了。 有人曾指出应先减48再加ch,其实先加再减即使爆int了也没事的。(想一想,为什么) $ $ ### 2.略慢一点的: 可以筛掉空格、回车、Tab和大小写字母 ```cpp inline int read() { register char ch=getchar(); register int x=0; while(!(ch&16)&&(ch&64))ch=getchar(); while((ch&16)&&!(ch&64))x=(x<<1)+(x<<3)+ch-48,ch=getchar(); return x; } inline int signed_read() { register char ch=getchar(); register int x=0; register bool b=0; while(!(ch&16)&&(ch&64)&&ch!='-')ch=getchar(); (ch=='-')&&(b=1,ch=getchar()); while((ch&16)&&!(ch&64))x=(x<<1)+(x<<3)+ch-48,ch=getchar(); b&&(x=-x); return x; } ``` $ $ ### 3.最常用的,顺便把print()放到这儿: ```cpp inline int read() { register char ch=getchar(); register int x=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-48,ch=getchar(); return x; } inline int signed_read() { register char ch=getchar(); register int x=0; register bool b=0; while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); (ch=='-')&&(b=1,ch=getchar()); while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-48,ch=getchar(); b&&(x=-x); return x; } #include<limits.h>//别忘了 inline void print(int x) { if(!x){putchar('0');return;} register short cnt=0;//有位大神(没记错是cz)说过,一般电脑short寄存器很少,所以常常reigster short比register int还慢。确实是的。 char ch[11]; (x&INT_MIN)&&(putchar('-'),x=-x); while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } inline void unsigned_print(int x)//参数可以改成unsigned修饰的类型,但一般为了和程序主体兼容还是用带符号的。下同。 { if(!x){putchar('0');return;} register short cnt=0; char ch[11]; while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } ``` $ $ ### 4.不需要`limits.h`的: ```cpp inline void print(int x) { if(!x){putchar('0');return;} register short cnt=0; char ch[11]; (x&2147483648u)&&(putchar('-'),x=-x); while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } ``` $ $ ## $\mathtt{\color{#cc0505}\text{注意以上所有内容都会在输出-2147483648时爆炸}}$ ### 5.最稳定不会炸的版本: ```cpp inline void putstr(const char *ch)//注意没有const会警告 不要忘了这个函数,不然十年OI一场空! { while(*ch)putchar(*(ch++)); } inline void print(int x) { if(!x){putchar('0');return;} if(x==2147483648u){putstr("-2147483648");return;} register short cnt=0; char ch[11]; (x&2147483648u)&&(putchar('-'),x=-x); while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } inline void unsigned_print(int x) { if(!x){putchar('0');return;} register short cnt=0; char ch[11]; while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } ``` $ $ 还有一个`print2`,用累乘法跟`print`效率不相上下(在洛谷IDE和某些OJ上`print2`快,在自家i3古董上`print`快一些) ```cpp inline void print2(int x) { if(!x){putchar('0');return;} if(x==2147483648u){printf("-2147483648");return;} (x&2147483648u)&&(putchar('-'),x=-x); if(x==1000000000){printf("1000000000");return;}//防止在1e9时出锅 (x>1000000000)&&(putchar(x/1000000000+48),x%=1000000000);//防止在1e9以上时出锅 register int cnt=1; while(cnt<=x)cnt*=10; while(cnt/=10)putchar(x/cnt+48),x%=cnt; } inline void unsigned_print2(int x) { if(!x){putchar('0');return;} if(x==1000000000){printf("1000000000");return;} (x>1000000000)&&(putchar(x/1000000000+48),x%=1000000000); register int cnt=1; while(cnt<=x)cnt*=10; while(cnt/=10)putchar(x/cnt+48),x%=cnt; } ``` $ $ $ $ ### 6.其他乱七八糟的: ```cpp inline long long readll() { register char ch=getchar(); register long long x=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar(); return x; } inline long long signed_readll() { register char ch=getchar(); register bool b=true; register long long x=0; while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); (ch=='-')&&(b=1,ch=getchar()); while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-48,ch=getchar(); b&&(x=-x); return x; } inline void print(long long x) { if(!x){putchar('0');return;} register short cnt=0; char ch[21]; // (x&-9223372036854775808ll)&&(putchar('-'),x=-x);这个注释是干什么的我就不说了 (x&LONG_LONG_MIN)&&(putchar('-'),x=-x); while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } inline void unsigned_print(long long x) { if(!x){putchar('0');return;} register short cnt=0; char ch[21]; while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } inline __int128 read128() { register char ch=getchar(); register __int128 x=0; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar(); return x; } inline __int128 signed_read128() { register char ch=getchar(); register bool b=true; register __int128 x=0; while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); (ch=='-')&&(b=1,ch=getchar()); while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-48,ch=getchar(); b&&(x=-x); return x; } inline void print(__int128 x) { if(!x){putchar('0');return;} register short cnt=0; char ch[42]; (x<0)&&(putchar('-'),x=-x); while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } inline void unsigned_print(__int128 x) { if(!x){putchar('0');return;} register short cnt=0; char ch[42]; while(x)ch[cnt++]=x%10+48,x/=10; while(cnt--)putchar(ch[cnt]); } ``` //wait to be updated ### 鸣谢