cstdio
分享中搜关键字“快速读入-wow”,认准唯一优质分享
对于习惯iostream的同学而言,改成cstdio是很难的。
但是,面对大数据量,cstdio明显在速度上占优势。
怎么办呢?
要输入一些字符串时,string无疑是最好的选择
传统的cstdio无法与string匹配
但是使用scanf支持的char数组又显得很不方便,尤其是在比较字符串时。
所以我们就要结合双方的优点。
将string和cstdio 结合。
请看~
输入
inline void read(string &s)
{
char ch=getchar() ;
while(ch<'a'||ch>'z') ch=getchar() ;
while(ch>='a'&&ch<='z')
{
s+=ch ;
ch=getchar() ;
}
}
输出
inline void print(string s)
{
puts(s.cstr()) ; //可以化为char类数组再用puts/printf
}
那输入时为什么不能这样呢?
inline void read(string &s)
{
char *ch ;
gets(ch) ;
s=ch ;
}
但在c++中,gets是被禁用的,所以会这样:
the 'gets' function is dangerous and should not be used.
我们还是用前面的方法吧。
注:在c++中,gets不能用,但puts可用,可以输出一个char类型的数组,后面再加一个换行
实际上,不用gets
,用scanf不就行了嘛!
inline void read(string &s)
{
char* ch ;
scanf("%s",ch) ; //1.一般ch前要加&,转为指针变量,但这里ch已经是指针,不用加&可以用,加&会报错
s=ch ;
}
有人要问了:为何不能这样呢?
inline void read(string &s)
{
scanf("%s",s.c_str()) ;
}
c_str这个函数,是 一个函数的返回值,要存在字符串里 ,由于读入时是将输入流赋值到c_str,而没有赋值到string里,实际上没有读进去。
另外,C++11提供了一种新语法,叫“lambda表达式”
例如:
int add(int a,int b)
{
return a+b ;
}
int main()
{
int a,b ;
scanf("%d%d",&a,&b) ;
printf("%d",add(a+b)) ;
return 0 ;
}
改成
int main()
{
int a,b ;
scanf("%d%d",&a,&b) ;
auto add=[](int a,int b)
{
return a+b ;
} ;
printf("%d",add(a,b)) ;
return 0 ;
}
也能一定的提高效率
(可参考这篇文章: lambda表达式)
附:整数/浮点快速读入
在数据量超大时,为提升效率,需要组装整数
整数输入
inline void read(int &n)
{
int sign=1 ;
char ch=getchar() ;
while(ch<'0'||ch>'9')
{
if(ch=='-') sign=-1 ;
ch=getchar() ;
}
while(ch>='0'&&ch<='9')
{
n=(n<<1)+(n<<3)+ch-'0' ;
ch=getchar() ;
}
n*=sign ;
}
浮点输入
inline void read(double &n)
{
int sign=1 ;
char ch=getchar() ;
while(ch<'0'||ch>'9')
{
if(ch=='-') sign=-1 ;
ch=getchar() ;
}
bool flag=0 ;
int cnt=0 ;
while((ch>='0'&&ch<='9')||ch=='.')
{
if(isdigit(ch))
{
if(flag) n+=pow(0.1,++cnt)*(ch-'0') ;
else n=n*10-'0'+ch ;
}
else flag=1 ;
ch=getchar() ;
}
n*=sign ;
}
经过我的实验,函数只能保留五位小数,请慎用
但是,最能提高速度的方法是这样的
//手动加速
#pragma GCC optimize(2) //O2氧气优化
#pragma GCC optimize(3) //O3臭氧优化
本来20ms过的A+B,10ms就过了!
不过,在正式比赛上还是不要用,否则给你的就是禁赛三年