1. 程式人生 > >【模板】讀入優化&輸出優化

【模板】讀入優化&輸出優化

先列一份摘自LOJ的一份讀入測試資料(資料說明一切)
以下是若干讀入整數速度測試的結果(單位:毫秒)。
輸入:3×106 ​ 個在區間中隨機生成的十進位制整數。

# 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');
}