想必大家都在某种网站上看过下面这种情况。
之所以,会出现这种情况,是因为 C++ 作为 C 语言的超集,为了兼容 C语言 ,做了很多额外的工作,所以用
为了支持 流输入/输出 和 格式化输入/输出 之间的搭配,cout / cin 的每一次操作完成后都会将内部缓冲区和 printf / scanf 的缓冲区同步。
对于上述问题,我们可以采用下面这条语句(写在主函数中)取消同步。
std::ios::sync_with_stdio(false);//取消同步
但是这样我们就不能在读入数据时交叉使用 流输入(cin)/输出(cout) 和 格式化输入(scanf();)/输出(printf();) 了。
例:
#include
#include
int main(void){
std::ios::sync_with_stdio(false);//取消同步
freopen("data.txt","r",stdin);//data.txt中为数字 0~999999
freopen("res.txt","w",stdout);
for(int i=0,n1,n2;i<1000000;i+=2){
scanf("%d",&n1);
std::cin>>n2;
printf("%d %d ",n1,n2);
}
return 0;
}
data.txt(截取)
res.txt(截取)
在取消同步以后,scanf(); 仍旧比 cin 要快得多,scanf(); 早已经读入0~40了, cin 才开始缓慢行动,读入41。
为了解决这一尴尬的问题,我们最好在NOI\NOIP、ACM等算法竞赛中不使用
万一格式化输入输出还不够快怎么办?
万一格式化输入输出还不够快怎么办??
万一格式化输入输出还不够快怎么办???
例如下面这个程序
#include
int main(void){
freopen("data.txt","r",stdin);//data.txt中为数字 0~999999
freopen("res.txt","w",stdout);
for(int i=0,n;i<1000000;i++)
scanf("%d",&n),printf("%d ",n);
return 0;
}
运行用了 0.4404s (多次实验时超过 0.5s ),这已经用了近一半的时间了。
是时候使用大杀器—— 读入优化&输出优化 了。
读入优化:
int read(int &x){
int f=1;char ch;x=0;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||'9'
原理:众所周知, ch=getchar(); 在读入字符方面比 scanf("%c",&ch); 快得多。
所以,我们完全可以利用 getchar(); 来加快文件读入速度。
输出优化:
void write(int x){
if(x<0){putchar('-');x=-x;}//若x为负数,输出符号并取其绝对值
if(x>9){write(x/10);putchar(x%10+'0');}//输出绝对值(采用递归的做法,减少代码量)
else putchar(x+'0');
return;
}
原理:同样的, putchar(); 在读入字符方面比 printf(); 快得多。
所以,我们完全可以利用 putchar(); 来加快文件读入速度。
优化后:
#include
int read(int &x){
int f=1;char ch;x=0;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||'9'9){write(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
int main(void){
freopen("data.txt","r",stdin);//data.txt中为数字 0~999999
freopen("res.txt","w",stdout);
for(int i=0,n;i<1000000;i++)
read(n),write(n),putchar(' ');
return 0;
}
比 格式化输入/输出 快了近一倍(0.2s)!!!
.
.
.
其实,输出优化还有一种做法:
将所有准备输出的数据放进一个大字符串(类似输入输出流的缓冲区)中,在程序结束之前用 printf("%s",str); 输出(清空缓冲区),在此因为难以演示,就不做过多说明了。
最好在平时练习算法时就多运用 读入优化 和 输出优化 ,才能在比赛时迅速读入输出数据。