读入优化 和 输出优化

想必大家都在某种网站上看过下面这种情况。

之所以,会出现这种情况,是因为 C++ 作为 C 语言的超集,为了兼容 C语言 ,做了很多额外的工作,所以用<iostream>时有不少东西需要注意。

为了支持 流输入/输出 和 格式化输入/输出 之间的搭配,cout / cin 的每一次操作完成后都会将内部缓冲区和 printf / scanf 的缓冲区同步。

对于上述问题,我们可以采用下面这条语句(写在主函数中取消同步。

std::ios::sync_with_stdio(false);//取消同步

但是这样我们就不能在读入数据时交叉使用 流输入(cin)/输出(cout) 和 格式化输入(scanf();)/输出(printf();) 了。

例:

#include<stdio.h>
#include<iostream>
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等算法竞赛中不使用<iostream>


万一格式化输入输出还不够快怎么办?

万一格式化输入输出还不够快怎么办??

万一格式化输入输出还不够快怎么办???

例如下面这个程序

#include<stdio.h>
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);//读入符号或其他字符
	while('0'<=ch&&ch<='9'){x=10*x+ch-'0';ch=getchar();}x*=f;//读入x的绝对值并加上符号
	return x;
}

原理:众所周知, 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<stdio.h>
int read(int &x){
	int f=1;char ch;x=0;
	do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||'9'<ch);
	while('0'<=ch&&ch<='9'){x=10*x+ch-'0';ch=getchar();}x*=f;
	return x;
}
void write(int x){
	if(x<0){putchar('-');x=-x;}
	if(x>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); 输出(清空缓冲区),在此因为难以演示,就不做过多说明了。

最好在平时练习算法时就多运用 读入优化 和 输出优化 ,才能在比赛时迅速读入输出数据。

猜你喜欢

转载自blog.csdn.net/lu_anlai/article/details/79344505