cin.tie与sync_with_stdio加速I/O

以前总是听说C++的cincout效率低下,导致我在做算法题的时候总是使用C风格的scanfprintf,敲起来真是麻烦得多2333
后来经过学习才发现,其实C++为了兼容C,而在i/o上做了一些文章,cincout经过手动配置,也能够胜任在算法中的工作

std::cin做了额外的工作

cin之所以显得慢,是因为出于安全考虑,做了以下两个工作:

  • std::cout 绑定。每次 std::cin 从缓冲区读入内容之前,会执行 std::cout.flush()刷新缓冲。
  • stdio 同步。确保混用 C 风格的 I/O 操作如(scanfprintf)不会引发问题。

而如果在编码时能够人为地避免这些问题,就可以省去这些工作,从而达到加速cin的目的。

std::cin.tie

cin.tie是将cin和某个ostream绑定的函数,空参数的话返回当前的输出流指针。
根据 cplusplus网站 的描述,根据传递的参数不同,该函数具有两种功能:

  • (1)无参调用: ostream* tie() const;
  • (2)含参调用: ostream* tie (ostream* tiestr);

The first form (1) returns a pointer to the tied output stream.
形式(1)返回当前绑定的输出流指针
The second form (2) ties the object to tiestr and returns a pointer to the stream tied before the call, if any.
形式(2)将cin和tiestr绑定,并返回在这之前绑定的流指针(如果有的话)
The tied stream is an output stream object which is flushed before each i/o operation in this stream object.
绑定的流是一个输出流对象,该对象在每次 i/o 操作之前都会进行刷新。

cplusplus网站还有一个代码示例,为方便理解,在这里贴出我添加了注释的版本:

// redefine tied object
#include <iostream>     // std::ostream, std::cout, std::cin
#include <fstream>      // std::ofstream

int main() {
	std::ostream* prevstr;
	std::ofstream ofs;
	// ofs 绑定文件 test.txt
	ofs.open("test.txt");

	// 控制台输出
	std::cout << "tie example:\n";

	// cin.tie 返回 std::cout 的指针,字符串输出到控制台
	*std::cin.tie() << "This is inserted into cout";
	// 将文件输出流 ofs 绑定在 std::cin 上
	// 同时返回原先绑定在cin上的输出流指针(指向控制台输出)
	prevstr = std::cin.tie(&ofs);
	// cin.tie 返回 ofs 的指针,字符串输出到文件 test.txt
	*std::cin.tie() << "This is inserted into the file";
	// 恢复为控制台输出
	std::cin.tie(prevstr);
	// 关闭文件
	ofs.close();

	return 0;
}

利用形式(2),在默认状态下,我们可以通过给该函数传递空指针,从而解除cincout的绑定,省去了第一项额外工作的时间,具体代码如下:

std::cin.tie(nullptr);
//或者std::cin.tie(0);

ios::sync_with_stdio

调用该函数可以切换C++流和C流的同步状态
它的原型是:

static bool sync_with_stdio( bool sync = true )

这个同步是默认打开的,所以在默认情况下 C++ 流上做的操作会被同步到相应的 C 流中,这就为混和使用C++流和C流提供了可能。

倘若我们不混和使用C++流和C流(就比如在做算法题的时候),我们可以通过向该函数传递false参数值,以解除 C++ 流与 C 流的同步:

std::ios::sync_with_stdio(false);

这样一来第二项额外工作也免了。


所以,通过调用这两个函数,我们可以放心地将算法的I/O交给cincout处理,不用担心因为它们而TLE了

#include <iostream>

int main(){
	std::cin.tie(nullptr);
	std::ios::sync_with_stdio(false);

	// 然后写你的代码去吧...
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值