读优与写优
读优与写优是面对输入或者输出数据规模比较巨大的时候,cin和cout会TLE,即使是scanf和printf也会浪费大量时间,这时我们就可以使用读优与写优
一个小小的冷知识
cin和cout之所以慢,是因为它有很多的保险设置,浪费了时间,所以只要加入这段代码
1 std::ios::sync_with_stdio(false);
这样就可以取消cin和cout的保险装置
正经的读优与写优
原理
用cin和cout或者scanf和printf读写单个数字时,速度会比getchar和putchar读写单个字符慢很多,考虑到比起读写的时间,运算的时间几乎可以忽略不计,那么我们可以使用getchar和putchar按数位输入输出,加快读写速度
读入优化
基本原理
使用一个while过滤掉所有非数字的字符,并且判断正负,再用一个while把数字*10并读入下一位。这样我们需要一个字符变量来读入,需要两个整数变量来存储符号和数字的绝对值
代码
1 inline int qread() 2 { 3 char ch = getchar(); 4 int f = 1, x = 0;//f符号x绝对值 5 while(!(ch >= ‘0‘ && ch <= ‘9‘)) 6 { 7 if(ch == ‘-‘) f = -1;//判断符号 8 ch = getchar(); 9 } 10 while(ch >= ‘0‘ && ch <= ‘9‘) 11 { 12 x *= 10; 13 x += (ch & 15);//&15相当于-‘0‘,也就是字符转换成数字 14 ch = getchar(); 15 } 16 return f * x; 17 }
这就是常用的读优了。然而如果你比较懒,可以使用<cctype>库里面的isdigit(char)函数来判断一个字符是否是数字,但是可能对于低版本的编译器会出现一些玄学bug,所以还是推荐手动判断在‘0‘和‘9‘之间,这样,想读入一个int a,就可以这样
1 a = read();
如果你的整数时long long不是int,那么把读优函数类型和函数里面的int全部换成long long,就OK了。读优是一个很常用的操作,可以解决很多由于数据量大而TLE的问题。
输出优化
其实写入优化远不如读入优化常用,因为很多人懒得写。。。再说很多题是读入一堆,输出只有每行一个数。。。
一些改变
如果像读入优化一样按位输出,你会发现所有数字反了过来。如果写一个栈来存数,反而弄巧成拙了,那么可以用递归来实现
代码实现
我对面那台电脑上的大佬随手用递归写了一个写优函数
1 void print(int n) 2 { 3 if(n==0) return; 4 print(n/10); 5 putchar(n%10+‘0‘); 6 }
我一看,实属巧妙,它会把这个数字按照正确的顺序从左往右输出。然而,当数字为0的时候,它会什么也输出不出来,如果是负数会炸掉,所以我给它加工了一下
1 inline void print(int n) 2 { 3 if(n==0) return; 4 print(n/10); 5 putchar(n%10+‘0‘); 6 } 7 inline void qwrite(int n) 8 { 9 if(n==0) 10 { 11 putchar(‘0‘); 12 return; 13 } 14 if(n<1) 15 { 16 putchar(‘-‘); 17 n*=-1; 18 } 19 print(n); 20 }
这样,需要输出一个整数a时,就可以这样实现了
1 qwrite(a);
重点!重点!重点!小数千万不要使用读写优化!这个读写优化只能用于整数!
原文地址:https://www.cnblogs.com/Juruo1103/p/10011237.html