【模板】读入优化&输出优化

先列一份摘自LOJ的一份读入测试数据(数据说明一切)
以下是若干读入整数速度测试的结果(单位:毫秒)。
输入: 3×106 3 × 10 6 ​ 个在区间中随机生成的十进制整数。

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

你可能感兴趣的:(优化)