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

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

#Lanuage[0,2)[0,8)[0,215)[0, 231)[0,263)
freadG++ 5.4.0 (-O2)13133970111
getcharG++ 5.4.0 (-O2)5873137243423
cin(关闭同步)G++ 5.4.0 (-O2)161147205270394
cinG++ 5.4.0 (-O2)44242970610391683
scanfG++ 5.4.0 (-O2)182175256368574

现在,我们看数据,就可以说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');
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值