输入输出优化集锦
team109
2019-08-11 22:10:29
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
### 鸣谢