读入优化&输出优化 (C++) 详解

读入优化&输出优化 (C++) 详解

写在前面

本文主要介绍了C++读入和输出的一些性质和优化

希望对读者有所帮助

cin/cout

大家对这个应该很熟悉了吧?想必最开始接触 \(OI\) 的时候大家写的输入输出就是用的这个吧。

其实你做多了题目就会发现这个 \(cin\)\(cout\) 是非常慢的,因为它从缓冲区中读入数据。

而这个缓冲常常是同步的,因为它还需要辨别输入类型。

为了加速这个东西,所以我们可以在代码中加入这样一句话,意为关闭同步流:

ios::sync_with_stdio(false);

然后再次使用 \(cin\)\(cout\) 就会变得很快了。

但是在大量的数据面前,它的表现仍然不够出色,常常有 \(TLE\) 的存在。

scanf/printf

这个东西应该是大多数较为自身的\(Oler\) 在用的东西了。

因为它还要加上什么格式符而为广大初学者所不喜欢。

· 但是请注意:** 它很快!**

但是它也有一个坏处,相信很多做过字符串题目的 \(Oler\) 应该清楚,这个scanf可能读入一个换行符!

这里解释下原因:\(Linux\)\(Windows\) 下换行符是不一样的!

至于哪里不一样读者可以查阅网上资料,这里只做原因解释,因此如果读入字符且有换行之类,建议读一句

scanf("\n");

然后就没有什么好说的了 \(QAQ\)

` ** 等等,你不是说这个很快嘛,我怎么呢在数据超过 \(100w\) 因为它而 \(TLE\) 了? **

因为它还不够快!

read()/output()

这两个函数就不要期望 C++ 还会给你配置了,为了更快的读入,只能手写了咯

原理:\(getchar()/putchar()\)速度较快。

我们按照高精度的方式,可以把数字当做字符读入/输出,最后再转化为数字,这样会更快。

· ** 起码它在 \(100w\) 以上的数据量表现得很强势! **

那么我们模拟实现即可:

inline void read() {
    static bool f;
    static char c;
    static int x;
    
    while(!isdigit(c = getchar()) && c != '-');
    x = (f = c == '-') ? 0 : c ^ 48;
    while(isidit(c = getchar()))
        x = (x << 3) + (x << 1) + (c ^ 48);
    return f ? ~x + 1 : x;
}

inline void output(int x) {
#define reg register    
    static char buf[30], *tail = buf;
    if(x == 0) putchar('0');
    else {
        if(x < 0) x = ~x + 1, putchar('-');
        for(; x; x /= 10) *++tail = (x % 10) ^ 48;
        for(; tail != buf; --tail) putchar(*tail);
    } putchar('\n');
}

里面运用\(x=(x<<3)+(x<<1)+(c^48)\)是因为位运算会快于四则远算。

至于这边可以采用 \(c^48=c-48\),因为 \(0\) 的 二进制 下编码为 \(48\),你会发现 \(0-9\) 的 二进制表示 在 \(48\) 的二进制下表示刚好错开。

我们刚好可以利用这个性质进行优化,对于输出自然是一样。

` ** 它还不够快?**

Superread()/Superwrite()

顾名思义,超级快读和超级快输。

猜你喜欢

转载自www.cnblogs.com/Ning-H/p/11740875.html