700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C++为什么空格无法输出_算法竞赛C++常用技巧——输入输出优化(防止TLE)

C++为什么空格无法输出_算法竞赛C++常用技巧——输入输出优化(防止TLE)

时间:2019-10-25 13:34:57

相关推荐

C++为什么空格无法输出_算法竞赛C++常用技巧——输入输出优化(防止TLE)

cin、cout优化

在默认情况下,std::cin/std::cout 是极为迟缓的输入/输出方式,而 scanf/printf 比 std::cin/std::cout 快得多。

可是为什么会这样呢?如果我更习惯使用C++的输出方式,那么有没有什么办法解决输入输出缓慢的问题呢?

这是因为在默认情况下,cin与stdin总是保持同步的,也就是说这两种方法可以混用,而不必担心文件指针混乱,同时cout和stdout也一样,两者混用不会输出顺序错乱。由于这个特性,所以导致cin和cout有许多额外的开销。

那么我们如何禁用这个特性呢?

关闭同步/解除绑定

std::ios::sync_with_stdio(false)这个函数是一个“是否兼容 stdio”的开关,C++ 为了兼容 C,保证程序在使用了 printf 和 std::cout 的时候不发生混乱,将输出流绑到了一起。

这其实是 C++ 为了兼容而采取的保守措施。我们可以在进行 IO 操作之前将 stdio 解除绑定,但是在这样做之后要注意不能同时使用std::cin/std::coutscanf/printf。更严格的来说:关闭之后C++ IO和C IO 两者不能混用,否则会造成IO混乱。

tie函数加速

还有一种影响速度的原因是:在默认的情况下std::cin绑定的是std::cout,每次执行 << 操作符的时候都要调用flush(),这样会增加 IO 负担。

tie 是将两个 stream 绑定的函数,空参数的话返回当前的输出流指针。可以通过std::cin.tie(0) 和std:cout.tie(0)(0 表示 NULL)来解除std::cinstd::cout的绑定,进一步加快执行效率。

在这两种情况优化下,std::cin和std::cout的速度就和scanf和printf基本一样了,甚至更快。

代码实现

注意:

更快的输入优化getchar()

原理

众所周知, getchar 是用来读入 1 byte 的数据并将其转换为 char 类型的函数,且速度很快,故可以用“读入字符——转换为整型”来代替缓慢的读入

每个整数由两部分组成——符号和数字,整数的 ‘+’ 通常是省略的,且不会对后面数字所代表的值产生影响,而 ‘-’ 不可省略,因此要进行判定。

10 进制整数中是不含空格或除 0~9 和正负号外的其他字符的,因此在读入不应存在于整数中的字符(通常为空格)时,就可以判定已经读入结束

C 和 C++ 语言分别在 ctype.h 和 cctype 头文件中,提供了函数 isdigit , 这个函数会检查传入的参数是否为十进制数字字符,是则返回 true ,否则返回 false。对应的,在下面的代码中,可以使用 isdigit(ch) 代替 ch >= ‘0’ && ch <= ‘9’ ,而可以使用 !isdigit(ch) 代替 ch ‘9’。

代码实现输入函数read()

举例:我们输入数据时可以这样调用read函数:num=read()

更快的输出优化putchar()

原理

同样是众所周知,putchar是用来输出单个字符的函数,因此将数字的每一位转化为字符输出以加速,要注意的是,负号要单独判断输出,并且每次 %(mod)取出的是数字末位,因此要倒序输出。

代码实现

递归版

由于递归的任务量比较大,我们可以利用栈来实现非递归。

非递归版

OK,这就是经典的输入输出的优化做法,通常cf榜上的大佬用的都是后面这种方法,这确实很快,比scanf和printf快了约1 / 3 1/31/3了吧。我自己常用的就是第一种优化方法,通常我会利用宏定义来避免这么繁琐,如:#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)

那么,在主函数直接使用IOS;语句即可实现优化功能。

编辑整理 丨田培辰

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。