【模板】讀入優化&輸出優化
阿新 • • 發佈:2019-02-15
先列一份摘自LOJ的一份讀入測試資料(資料說明一切)
以下是若干讀入整數速度測試的結果(單位:毫秒)。
輸入: 個在區間中隨機生成的十進位制整數。
# | Lanuage | [0,2) | [0,8) | [0,215) | [0, 231) | [0,263) |
---|---|---|---|---|---|---|
fread | G++ 5.4.0 (-O2) | 13 | 13 | 39 | 70 | 111 |
getchar | G++ 5.4.0 (-O2) | 58 | 73 | 137 | 243 | 423 |
cin(關閉同步) | G++ 5.4.0 (-O2) | 161 | 147 | 205 | 270 | 394 |
cin | G++ 5.4.0 (-O2) | 442 | 429 | 706 | 1039 | 1683 |
scanf | G++ 5.4.0 (-O2) | 182 | 175 | 256 | 368 | 574 |
現在,我們看資料,就可以說fread無敵了,,,
現在進入正題,讀取方式就看程式吧(模板就是用來背的嘛)。
我把兩個讀入輸出優化分別封裝在了兩個namespace裡面,主程式中呼叫using namespace就可以了。
namespace Istream {
static const int BUF = 50000000;
inline char get() {
static char buf[BUF], *h, *t;
h == t ? t = (h = buf) + fread(buf, 1, BUF, stdin) : 0;
return h == t ? -1 : *h++;
}
inline int getint() {
int num = 0, symbol = 1;
char ch = get();
while (!isdigit(ch)) {
if (ch == -1) return 0;
ch == '-' ? symbol = -1 : 0;
ch = get();
}
while (isdigit(ch))
num = (num << 3) + (num << 1) + (ch ^ '0'),
ch = get();
return num * symbol;
}
}
這個是讀入的namespace,主程式中需要像getchar()一樣一個一個讀。
namespace Ostream {
static const int BUF = 50000000;
char buf[BUF], *h = buf;
inline void put(char ch) {
h == buf + BUF ? (fwrite(buf, 1, BUF, stdout), h = buf) : 0;
*h++ = ch;
}
inline void putint(int num) {
static char _buf[30];
sprintf(buf, "%d", num);
for (char *s = _buf; *s; s++) put(*s);
put('\n');
}
inline void finish() {
fwrite(buf, 1, h - buf, stdout);
}
}
這是輸出優化(並不常用),就貼在這吧,用的時候拿一拿就可以了
另外,由於本人有時候改程式碼經常忘了寫輸出優化後面的結末輸出。再貼上一個struct版本的fread,最大優點就是在構造和解構函式中執行了fread和fwrite
const int BUF = 50000000;
struct IOStream {
char ibuf[BUF], *s;
char obuf[BUF], *oh;
IOStream() : s(ibuf), oh(obuf) {
ibuf[fread(ibuf, 1, BUFFER_SIZE, stdin)] = '\0';
}
~IOStream() {
fwrite(obuf, 1, oh - obuf, stdout);
}
template <typename T>
inline IOStream &operator >> (T &x) {
while (!isdigit(*s)) s++;
for (x = 0; isdigit(*s); s++) x = x * 10 + (*s ^ '0');
return *this;
}
template <typename T>
inline IOStream &operator << (T x) {
static char buf[13];
register char *top = buf;
if (x != 0) {
for (register int t; x;) {
t = x / 10;
*top++ = x - t * 10 + 48;
x = t;
}
while (top != buf) *oh++ = *--top;
} else {
*oh++ = '0';
}
*oh++ = ' ';
return *this;
}
};
最後,由於本人fread經常寫殘,我再貼一個沒辦法時候的穩穩的getchar和putchar吧。
inline int getint() {
int num = 0, sign = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
ch == '-' ? sign = -1 : 1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
num = (num << 3) + (num << 1) + (ch ^ '0'),
ch = getchar();
return num * sign;
}
inline void putint(int num) {
if (num > 9) putint(num / 10);
putchar(num % 10 + '0');
}