クイック入出力クラス(C++)
4793 ワード
cin/coutは遅いのでscanf/printfが多いことを知っています.しかし、もっと厳しく、もっと速く要求すれば、どうすればいいですか.高速入出力という解決策があります.
高速入出力はgetchar()とputchar()関数を用い,数値加算法で入出力数を入力/出力する.
高速入出力をcin/coutのようにクラスとして定義することもできます.
コードは次のとおりです.
実は、高速出力は速くなく、coutよりも遅い.
数をすばやく入力できるようになりました!
——でも、テストしたの?qout出力浮動小数点数に問題があることに気づきましたか?qout出力浮動小数点数最下位はデテール法で出力されるので問題あり!時々、精度のせいで、元の数(例えば1.23)は少し減り、1 e-12しかないかもしれませんが、デテール法なので結果は1.2299になります.1.2345であれば1.2344になる可能性があります.だから--インタラクティブになりました!コメントエリアでq_ostream operator<(double double_num)の改良案(C++コード)に返信し、テストに合格しました(システム:Windows、IDE:Dev-C++、コンパイラ:g++)の方にご褒美があります:もしあなたが文章を書いたら(オリジナル/転載/翻訳でも構いません)、私はいくつかの文章(最大3編、文章数が3編未満であれば、私は全点賛)でいいねをします.(締め切り:2019年2月31日23:59)
はい、最後に使い方を話します.は一般にcin/coutのようにint aである.qin>>a; 出力に小数精度制御が必要な場合はqout<
コードの転載と使用方法のみを許可します.(インタラクティブな部分は転載しないでください!)転載する時に本文のリンクを添付してください:https://blog.csdn.net/weixin_41461277/article/details/84863301 .
高速入出力はgetchar()とputchar()関数を用い,数値加算法で入出力数を入力/出力する.
高速入出力をcin/coutのようにクラスとして定義することもできます.
コードは次のとおりです.
//qio.h
#ifndef MY_QIO_H
#define MY_QIO_H
#include
#include
#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=='
'||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=='
'||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=='
'||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=='
'||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)は少し減り、1 e-12しかないかもしれませんが、デテール法なので結果は1.2299になります.1.2345であれば1.2344になる可能性があります.だから--インタラクティブになりました!コメントエリアでq_ostream operator<(double double_num)の改良案(C++コード)に返信し、テストに合格しました(システム:Windows、IDE:Dev-C++、コンパイラ:g++)の方にご褒美があります:もしあなたが文章を書いたら(オリジナル/転載/翻訳でも構いません)、私はいくつかの文章(最大3編、文章数が3編未満であれば、私は全点賛)でいいねをします.(締め切り:2019年2月31日23:59)
はい、最後に使い方を話します.
コードの転載と使用方法のみを許可します.(インタラクティブな部分は転載しないでください!)転載する時に本文のリンクを添付してください:https://blog.csdn.net/weixin_41461277/article/details/84863301 .