クイック入出力クラス(C++)

4793 ワード

cin/coutは遅いのでscanf/printfが多いことを知っています.しかし、もっと厳しく、もっと速く要求すれば、どうすればいいですか.高速入出力という解決策があります.
高速入出力は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)
 
はい、最後に使い方を話します.
  • は一般にcin/coutのようにint aである.qin>>a;
  • 出力に小数精度制御が必要な場合はqout<

  •  
    コードの転載と使用方法のみを許可します.(インタラクティブな部分は転載しないでください!)転載する時に本文のリンクを添付してください:https://blog.csdn.net/weixin_41461277/article/details/84863301 .