1842: 快读代码

内存限制:128 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:0 解决:0

题目描述

在C++中,最常见的输入方法是:cin
快一点的就是:scanf();


那假如说scanf也不够快呢?
那就要用手写快读了,
下面是代码:

#include<iostream>
#include<cstdio>
using namespace std;

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}

int main(){

    return 0;
}
使用方法:

变量名=read() 


提示

前言
虽然读入优化好像用处不大,但是还是能够在读入数据规模较大的时候提供较大的优化,比如:

用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(){

}

————————————————

原文链接:https://blog.csdn.net/m0_73020012/article/details/133470285