UPD20191125:我发现我又丢人了,sgetc只会读取缓冲区当前字符而不会前移读取位置,想要读取并前移读取位置应该用sbumpc。。。
一般情况下,在C++中,iostream内的cin和cout是比scanf和printf慢的,这主要是为了同时兼容iostream和stdio,iostream与stdio的缓冲区被绑到了一起,以及cin和cout的stream是绑定在一起的,这使得cin和cout有额外的开销
为了提高cin和cout的效率,我们可以取消iostream与stdio的同步,以及cin和cout的stream的绑定:
1 std::ios::sync_with_stdio(false); 2 cin.tie(NULL); 3 cout.tie(NULL);
这样cin与cout就比scanf和printf快了。在本机测试上,iostream甚至比stdio快了6倍左右。然而这样做之后,就不可以将iostream与stdio混用了,然而输入量较大的时候,这种方法仍然无能为力
在stdin中,我们有getchar,想要追求更快的速度,我们有fread
在iostream中我们同样可以达到同样的效率,甚至更快:
首先要获取cin的streambuf:
std::streambuf *fb = cin.rdbuf();
然后我们就可以进行类似stdio中的操作:
对于getchar,我们有sbumpc,它的用法等同于getchar,速度略快于getchar:
char ch = fb -> sbumpc();
对于fread,我们有sgetn,它的用法与fread类似,速度略快于fread:
#define MAX_INPUT 1000000 char buf[MAX_INPUT] int main() { fb -> sgetn(buf, MAX_INPUT); return 0; }
输入问题就解决了。还有输出问题:
(不知道为什么,网上的输出代码在我这边不会进行输出,然而我这边手写的输出比fwrite慢了好多。。。。)
对于putchar,我们有sputc,它的用法等同于putchar,速度略快于putchar:
char ch = ' '; fb -> sputc(ch);
对于fwrite,我们有sputn,它的用法与fwrite类似,速度略快于fwrite?
#define MAX_OUTPUT 1000000 char buf[MAX_OUTPUT]; int main() { fb -> sputn(buf, MAX_OUTPUT); return 0; }
这样我们就有了一份完整的快速输入输出 丢人 代码(因为sputn的那份比sputc还慢,所以这里就用了sputc的代码):
#include<iostream> #include<cctype> using std::cin; using std::cout; using std::endl; namespace IN { #define MAX_INPUT 1000000 #define cinchar() ((fs == ft && (ft = (fs = buf) + fb -> sgetn(buf, MAX_INPUT))) ? 0 : *fs++) char buf[MAX_INPUT], *fs, *ft; inline int read() { static std::streambuf *fb = cin.rdbuf(); register int x = 0; register bool f = false; register char ch = cinchar(); while (!isdigit(ch)) { if (ch == '-') f = true; ch = cinchar(); } while (isdigit(ch)) { x = (x << 1) + (x << 3) + ch - '0'; ch = cinchar(); } return f ? -x : x ; } #undef MAX_INPUT #undef cinchar } namespace OUT { inline void put(int x) { static std::streambuf *fb = cout.rdbuf(); static char stack[11]; static int top = 0; if (!x) { fb -> sputc('0'); fb -> sputc(' '); return; } while (x) { stack[++top] = x % 10 + '0'; x /= 10; } while (top) { fb -> sputc(stack[top]); --top; } fb -> sputc(' '); } } int main() { freopen("add.in", "r", stdin); std::ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int a = IN::read(), b = IN::read(); OUT::put(a + b); return 0; }
为了丢人,在这里贴上sputn的代码
1 namespace OUT { 2 #define MAX_OUTPUT 1000000 3 char buf[MAX_OUTPUT], *fs = buf, *ft = buf + MAX_OUTPUT; 4 #define coutchar(ch) *fs++ = ch 5 inline void put(int x) { 6 static std::streambuf *fb = cout.rdbuf(); 7 static char stack[11]; 8 static int top = 0; 9 if (!x) { 10 coutchar('0'); coutchar(' '); 11 return; 12 } 13 while (x) { 14 stack[++top] = x % 10 + '0'; 15 x /= 10; 16 } 17 while (top) { 18 *fs++ = stack[top]; 19 --top; 20 } 21 coutchar(' '); 22 fb -> sputn(buf, fs - buf); 23 fs = buf; 24 } 25 #undef coutchar 26 #undef MAX_OUTPUT 27 }
代码部分参考自:https://blog.csdn.net/simpsonk/article/details/78457842