C++快读和快写
前言
虽然读入优化好像用处不大,但是还是能够在读入数据规模较大的时候提供较大的优化,比如:
用cin输出2000个100000000
用快输输出2000个100000000
单位都是毫秒。可以直观的发现,用快输的话输出时间优化了很多,那么快读是如何做到这样的呢?
原理
众所周知,在c++中,用putchar和getchar输入输出字符的速度是很快的,因此,我们可以考虑把数字转化为字符,按位输出;把字符读入后转化为数字的每一位。
快读
普通快读:
可以读入任意整数类型的变量
template<typename T>inline void readT(T &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
读入__int128:
__int128只能用快读读入
inline void read128(__int128 &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
超级快读:
经实测,只能读入整数
char buf[1<<20],*p1,*p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin), p1 == p2) ? 0 : *p1++)
template<typename T>inline void readT(T &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
inline void read128(__int128 &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
读入字符串(string类型,不能读入空格)
循环读入每一位就可以了
inline void readS(std::string &s){
char ch=getchar();
while(ch==' '||ch=='\n') ch=getchar();
while(ch!=' '&&ch!='\n') s+=ch,ch=getchar();
}
读入字符串(string类型,读入一行)
同上,循环读入每一位,不过判断的时候把空格保留就可以了
inline void readSL(std::string &s){
char ch=getchar();
while(ch=='\n') ch=getchar();
while(ch!='\n') s+=ch,ch=getchar();
}
读入字符串(char数组型,不能读入空格)
原理同string
inline int readC(char s[]){
int tot=0;char ch=getchar();
while(ch==' '||ch=='\n') ch=getchar();
while(ch!=' '&&ch!='\n') s[tot++]=ch,ch=getchar();
return tot;
}
读入单个字符(不读入空格和换行)
inline void readc(char &c){
c=getchar();
while(c==' '||c=='\n')
c=getchar();
}
因为受精度的影响,快读读入double的时候会出现比较大的误差,所以推荐使用scanf
快输
普通快输
可以输出常规的整数类型
template<typename T>
inline void writeT(T x){
if(x<0) putchar('-'),x=-x;
if(x>9) writeT(x/10);
putchar(x%10+'0');return;
}
输出__int128
inline void read128(__int128 &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
输出字符串
inline void writeS(std::string s){
int len=s.length();
for(int i=0;i<len;i++)
putchar(s[i]);
}
输出单个字符直接用putchar就可以了,同样,输出高精度数直接使用printf吧
读入、输出多个
读入多个
使用template的可变展开
template<typename T>inline void read(T& x) {
x = 0; bool f = false; char ch = getchar();
while (ch < '0' || ch>'9') { if (ch == '-') f = !f; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); }
x = (f ? -x : x); return;
}
template<typename T,typename... Args>
inline void read(T& x,Args&...x_){read(x),read(x_...);}
输出多个
同理
template<typename T>inline void put(T x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) put(x / 10);
putchar(x % 10 + '0'); return;
}template<typename T>inline void write(T x) {put(x);}
template<typename T,typename... Args>
inline void write(T x,Args...x_){write(x),write(x_...);}
能够支持几乎所有类型的快读快写模板
使用命名空间,使用的时候注意变量名的重复,因为string无法直接比较,所以存在了变量里,使用的时候直接调用write和read函数就可以了,但是字符串的话需要put函数和readS函数
#include<bits/stdc++.h>
namespace Std{
//不能读入char
// char buf[1<<20],*p1,*p2;
// #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin), p1 == p2) ? 0 : *p1++)
inline void read128(__int128 &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
inline void write128(__int128 x){
if(x<0) putchar('-'),x=-x;
if(x>9) write128(x/10);
putchar(x%10+'0');return;
}
inline void readD(double &x){scanf("%lf",&x);}
inline void writeD(double x){printf("%lf",x);}
inline void writeD(double x,int len){printf("%.*lf",len,x);}
template<typename T>inline void readT(T &x){
bool f=1;x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=(f?x:-x);return;
}
template<typename T>
inline void writeT(T x){
if(x<0) putchar('-'),x=-x;
if(x>9) writeT(x/10);
putchar(x%10+'0');return;
}
inline void readS(std::string &s){
char ch=getchar();
while(ch==' '||ch=='\n') ch=getchar();
while(ch!=' '&&ch!='\n') s+=ch,ch=getchar();
}
inline void readSL(std::string &s){
char ch=getchar();
while(ch=='\n') ch=getchar();
while(ch!='\n') s+=ch,ch=getchar();
}
inline void writeS(std::string s){
int len=s.length();
for(int i=0;i<len;i++)
putchar(s[i]);
}
inline int readC(char s[]){
int tot=0;char ch=getchar();
while(ch==' '||ch=='\n') ch=getchar();
while(ch!=' '&&ch!='\n') s[tot++]=ch,ch=getchar();
return tot;
}
inline void writeC(char s[],int len){
for(int i=0;i<len;i++)
putchar(s[i]);
}
inline void readc(char &c){
c=getchar();
while(c==' '||c=='\n')
c=getchar();
}inline void writec(char c){putchar(c);}
const std::string c="c";
const std::string i="i";
const std::string j="j";
const std::string X="x";
const std::string y="y";
const std::string b="b";
const std::string s="s";
const std::string Ss="Ss";
template<class T>
inline void read(T &x) {
if(typeid(x).name()==i) readT(x);
else if(typeid(x).name()==j) readT(x);
else if(typeid(x).name()==X) readT(x);
else if(typeid(x).name()==y) readT(x);
if(typeid(x).name()==b){
int k;readT(k);
x=(k>0?true:false);
}else if(typeid(x).name()==s) readT(x);
else if(typeid(x).name()==c){char ch;readc(ch);x=ch;}
}
template<class T,class... Ts>
inline void read(T &x,Ts&... xx){
if(typeid(x).name()==i) readT(x);
else if(typeid(x).name()==j) readT(x);
else if(typeid(x).name()==X) readT(x);
else if(typeid(x).name()==y) readT(x);
if(typeid(x).name()==b){
int k;readT(k);
x=(k>0?true:false);
}else if(typeid(x).name()==s) readT(x);
else if(typeid(x).name()==c){char ch;readc(ch);x=ch;}
read(xx...);
}
inline void read(std::string &x){readS(x);}
inline void read(char x[]){readC(x);}
inline void read(double &x){readD(x);}
inline void write(double x){writeD(x);}
inline void write(double x,int len){writeD(x,len);}
inline void write(std::string x){writeS(x);}
inline void write(char x[]){writeC(x,strlen(x));}
inline void write(double x,char a){writeD(x);putchar(a);}
inline void write(std::string x,char a){writeS(x);putchar(a);}
inline void write(char x[],char a){writeC(x,strlen(x));putchar(a);}
inline void write(double x,int len,char a){writeD(x,len);putchar(a);}
template<class T>inline void write(T x,char a){
if(typeid(x).name()==i) writeT(x);
else if(typeid(x).name()==j) writeT(x);
else if(typeid(x).name()==X) writeT(x);
else if(typeid(x).name()==y) writeT(x);
if(typeid(x).name()==b){
if(x) writeT(1);
else writeT(0);
}else if(typeid(x).name()==s) writeT(x);
else if(typeid(x).name()==c){writec(x);}
putchar(a);
}
inline void write(double x,std::string a){writeD(x);writeS(a);}
inline void write(std::string x,std::string a){writeS(x);writeS(a);}
inline void write(char x[],std::string a){writeC(x,strlen(x));writeS(a);}
inline void write(double x,int len,std::string a){writeD(x,len);writeS(a);}
inline void write(char a,std::string s){writec(a);writeS(s);}
template<typename T>inline void write(T x,std::string a){
if(typeid(x).name()==i) writeT(x);
else if(typeid(x).name()==j) writeT(x);
else if(typeid(x).name()==X) writeT(x);
else if(typeid(x).name()==y) writeT(x);
if(typeid(x).name()==b){
if(x) writeT(1);
else writeT(0);
}else if(typeid(x).name()==s) writeT(x);
else if(typeid(x).name()==c){writec(x);}
writeS(a);
}
template<typename T>inline void write(T x){
if(typeid(x).name()==i) writeT(x);
else if(typeid(x).name()==j) writeT(x);
else if(typeid(x).name()==X) writeT(x);
else if(typeid(x).name()==y) writeT(x);
if(typeid(x).name()==b){
if(x) writeT(1);
else writeT(0);
}else if(typeid(x).name()==s) writeT(x);
else if(typeid(x).name()==c) writec(x);
}
template<typename T,typename... Ts>
inline void write(T x,Ts... xx){
if(typeid(x).name()==i) writeT(x);
else if(typeid(x).name()==j) writeT(x);
else if(typeid(x).name()==X) writeT(x);
else if(typeid(x).name()==y) writeT(x);
if(typeid(x).name()==b){
if(x) writeT(1);
else writeT(0);
}else if(typeid(x).name()==s) writeT(x);
else if(typeid(x).name()==c){writec(x);}
write(xx...);
}
inline void put(std::string s){
int len=s.length();
for(int i=0;i<len;i++){
putchar(s[i]);
}
}
}
using namespace Std;
using namespace std;
signed main(){
}
如果觉得有 帮助的话,给个免费的赞吧😀😀