前言
虽然读入优化好像用处不大,但是还是能够在读入数据规模较大的时候提供较大的优化,比如:
用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(){}
如果觉得有 帮助的话,给个免费的赞吧??