我们知道,cin/cout是很慢的,所以我们经常scanf/printf。但是如果要求更严格一些,速度要更快,该怎么办呢?有一种解决办法,那就是——快速输入输出。
快速输入输出采用getchar()和putchar()函数,用了数字累加的方法输入/输出数。
我们也可以把快速输入输出定义成类,就像cin/cout一样。
代码如下:
//qio.h
#ifndef MY_QIO_H
#define MY_QIO_H
#include<cstdio>
#include<cmath>
#define E_MINUS(i) pow(0.1,i)
#define E_PLUS(i) pow(10,i);
using std::getchar;
using std::pow;
using std::putchar;
//assistant function(al)s
struct precision_class{
struct prec_type{
int prec;
};
prec_type operator () (int precision__){
prec_type ans={precision__};
return ans;
}
}precision;
//qin
class q_istream{
public:
q_istream operator >> (int &int_num){
int_num=0;
bool is_nag=0;
for(int i=0;;++i){
char c=getchar();
if(c==' '||c=='\t'||c=='\n'||c==EOF) break;
if(i==0 && c=='-'){
is_nag=1;
continue;
}
if(i==0 && c=='+') continue;
int_num*=10;
int_num+=c-48;
}
if(is_nag) int_num=-int_num;
return *this;
}
q_istream operator >> (long long &long_long_num){
long_long_num=0;
bool is_nag=0;
for(int i=0;;++i){
char c=getchar();
if(c==' '||c=='\t'||c=='\n'||c==EOF) break;
if(i==0 && c=='-'){
is_nag=1;
continue;
}
if(i==0 && c=='+') continue;
long_long_num*=10;
long_long_num+=c-48;
}
if(is_nag) long_long_num=-long_long_num;
return *this;
}
q_istream operator >> (unsigned long long &unsigned_long_long_num){
unsigned_long_long_num=0;
bool is_nag=0;
for(int i=0;;++i){
char c=getchar();
if(c==' '||c=='\t'||c=='\n'||c==EOF) break;
unsigned_long_long_num*=10;
unsigned_long_long_num+=c-48;
}
if(is_nag) unsigned_long_long_num=-unsigned_long_long_num;
return *this;
}
q_istream operator >> (double &double_num){
double_num=0;
bool is_nag=0;
for(int i=1;;++i){
char c=getchar();
if(c=='.') break;
if(i==1 && c=='-'){
is_nag=1;
continue;
}
if(i==1 && c=='+') continue;
double_num*=10;
double_num+=c-48;
}
for(int i=1;;++i){
char c=getchar();
if(c==' '||c=='\t'||c=='\n'||c==EOF) break;
double_num+=E_MINUS(i)*(c-48);
}
if(is_nag) double_num=-double_num;
return *this;
}
}qin;
//qout
class q_ostream{
private:
int precision;
public:
q_ostream(){
precision=4;
}
q_ostream operator << (int int_num){
char arr[20];
int i=0;
if(int_num<0) putchar('-'),int_num=-int_num;
while(int_num>0){
arr[i++]=(int_num%10+48);
int_num/=10;
}
while(i>0){
putchar(arr[--i]);
}
return *this;
}
q_ostream operator << (long long long_long_num){
char arr[30];
int i=0;
if(long_long_num<0) putchar('-'),long_long_num=-long_long_num;
while(long_long_num>0){
arr[i++]=(long_long_num%10+48);
long_long_num/=10;
}
while(i>0){
putchar(arr[--i]);
}
return *this;
}
q_ostream operator << (double double_num){
if(double_num<0) putchar('-'),double_num=-double_num;
int int_num=double_num;
if(int_num){
char arr[20];
int i=0;
if(int_num<0) putchar('-'),int_num=-int_num;
while(int_num>0){
arr[i++]=(int_num%10+48);
int_num/=10;
}
while(i>0){
putchar(arr[--i]);
}
}
else putchar('0');
int_num=double_num;
if(double_num-int_num<=E_MINUS(precision)) return *this;
putchar('.');
long long long_long_num=(double_num-int_num)*E_PLUS(precision);
{
char arr[30];
int i=0;
while(long_long_num>0){
int num_10=long_long_num%10;
arr[i++]=(num_10+48);
long_long_num/=10;
}
bool bef0=1;
while(i>0){
putchar(arr[--i]);
}
}
return *this;
}
q_ostream operator << (precision_class::prec_type precision_num){
precision=precision_num.prec;
return *this;
}
}qout;
#endif
其实,快速输出并不快,甚至比cout还要慢。
现在可以快速地输入一个数了!
——但是,你们测试了吗?你们有没有发现qout输出浮点数有点问题?因为qout输出浮点数最后一位是用去尾法输出的,所以会有问题!有时候,由于精度的原因,原来的数(比如1.23)会减一点点,可能只有1e-12,但是因为是去尾法,结果就变成了1.2299。如果是1.2345,那就有可能变成1.2344。所以——互动来了!在评论区中回复q_ostream operator << (double double_num)的改进方案(C++代码),测试通过(系统:Windows,IDE:Dev-C++,编译器:g++)的就会有奖励:如果你写了文章(原创/转载/翻译均可),那么我会在几篇文章(最多3篇,如果文章数量不够3篇,那么我会全点赞)中点赞。(截止时间:2018年12月31日23:59)
好,我最后说一下使用方法。
- 一般按cin/cout的方式,如 int a; qin>>a;
- 如果输出需要小数精度控制,用 qout<<precision(精度) 来调整精度。
只许转载代码和使用方法。(互动部分不许转载!)转载时请附上本文链接: https://blog.csdn.net/weixin_41461277/article/details/84863301 。