1.簡(jiǎn)介
自上一篇文章,我們了解了解除綁定的輸入輸出流,這會(huì)讓我們的代碼輸出變得迅速,然而,對(duì)于輸入而言,亦有快速讀取這一個(gè)更優(yōu)秀的方案(相對(duì)來說也較為麻煩)。
在我們學(xué)習(xí)C語言的時(shí)候,我們?cè)?jīng)學(xué)過字符的輸入函數(shù)getchar(),她從標(biāo)準(zhǔn)輸入里面讀取下一個(gè)字符,相當(dāng)于gets(stdin),返回類型為int型,為用戶輸入的ASCII碼,出錯(cuò)則返回-1。
2.實(shí)現(xiàn)方式
將所讀取的數(shù)據(jù)按位進(jìn)行分段截取,比如讀取入123這個(gè)數(shù)據(jù),在確定所讀取的是數(shù)字的情況下,先讀取數(shù)字1,如果其后還有數(shù)據(jù),將第一個(gè)讀取的數(shù)據(jù)1先乘以10再讀取第二個(gè)數(shù)據(jù)2,接著讀取3,將前面的12再乘以10,最后就可以讀取成功123,而對(duì)于負(fù)數(shù)而言,我們只需要設(shè)置一個(gè)flag標(biāo)記,對(duì)第一位的讀取進(jìn)行一個(gè)特判即可,在讀取完這些數(shù)據(jù)之后,將獲取到的整體數(shù)據(jù)進(jìn)行返回,這邊就是快讀的基本思想。
請(qǐng)記住這個(gè)核心:判斷是否為數(shù)字à按位讀取à轉(zhuǎn)換ASCII碼為數(shù)字à繼續(xù)讀取à進(jìn)行乘10與相加à讀取結(jié)束返回存儲(chǔ)的值
這里有一個(gè)簡(jiǎn)單版本的快讀
inline int read() { int X=0; bool flag=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();} while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();} if(flag) return X; return ~(X-1); }
使用inline重載函數(shù)和重寫read(),也可以去掉inline,只不過這樣效率稍微慢一些,輸入的使用方法就可以照做一般的函數(shù)進(jìn)行使用即可。
int tmp=read(); std::cout<<tmp<<std::endl;
3.擴(kuò)展,快速輸出
通快速讀取,亦有快讀輸出,其思想更為簡(jiǎn)單,效率也只是略微勝一籌,其思維是,按照每一位進(jìn)行拆解輸出,注意我們需要讓在后面的數(shù)字后輸出,拆解位時(shí)就務(wù)必要注意,因此,較為簡(jiǎn)單的方法就是模仿遞歸進(jìn)行設(shè)計(jì)。
inline void write(int X) { if(X<0) {X=~(X-1); putchar('-');} if(X>9) write(X/10); putchar(X%10+'0'); }
4. 推薦模板
使用C++的萬能模板類并創(chuàng)建新的命名空間IO,可以手動(dòng)指明所需要返回參數(shù)的類型,int還是long還是別的,這樣的方式更加人性化,可以省去上面那樣簡(jiǎn)單的方式必須手動(dòng)修改函數(shù)類型的缺點(diǎn),但是這樣的模板卻更加的復(fù)雜和繁長(zhǎng),不易快速上手使用,權(quán)且做一個(gè)理解。
#include<iostream> namespace IO { inline char nc() { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; } template<typename T> inline T read() { char ch = nc(); T sum = 0; while (!(ch >= '0'&&ch <= '9')) { ch = nc(); if (ch == EOF) return EOF; } while (ch >= '0'&&ch <= '9') { sum = sum * 10 + ch - 48; ch = nc(); if (ch == EOF) return EOF; } return sum; } } using namespace IO; int main(){ long long tmp=read<long long>(); //輸入方式 std::cout<<tmp<<std::endl; while(tmp = read<long long>()!=EOF){} //循環(huán)判斷EOF的方式 return 0; }
5.本篇后語
C++與STL篇就此結(jié)束了,本篇在模式上更趨向于雜談,STL內(nèi)容何其多,足足要近千頁的書才能講完講徹底,因此本章只是提出一個(gè)引子,一個(gè)簡(jiǎn)單的介紹,具體的內(nèi)容和內(nèi)涵需要多多自學(xué)完成,而對(duì)于快讀和解綁的操作,更加趨向于應(yīng)用在算法競(jìng)賽中搶的速度,具體如何搭配使用,也請(qǐng)自主根據(jù)數(shù)據(jù)規(guī)模進(jìn)行決斷。
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程
從零到寫出一個(gè)爬蟲的Python編程課程
只會(huì)語法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程