先列一份摘自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');
}