reserver_iterator 失效问题

真是蛋疼啊,今天打开牛客网,准备写一道生成Gray码的题目,结果居然发现了一个坑。

题目:

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。

给定一个整数n,请返回n位的格雷码,顺序为从0开始。

测试样例:

1
返回:["0","1"]

要求用递归,我的想法: 

1位: 0,1

2位 :00 ,01 ,11 ,10

3位: 000, 001 ,011, 010 ,   110 ,111 ,101 ,100

Gray(2)  -> Gray(3)       00 ,01 ,11 ,10每个前面加个0,变为000 ,001 ,011 ,010,把10,11,01,00前面加个1,变为110,111 ,101 ,100。就ok了。

 

class GrayCode {
public:
	vector<string> getGray(int n) {
		if (n <= 0) {
			return {};
		}
		if (n == 1) {
			return { "0","1" };
		}
		vector<string> v(getGray(n - 1));
		v.reserve(v.size() << 1);

		for(auto it = v.rbegin(); it != v.rend(); ++it){
			string& s = *it;
			v.emplace_back("1" + s);
			s.insert(s.begin(), '0');
		}
		return v;
	}
};

思路就是这样的,因为有插入动作,所以我先reserve了一下vector,想以此保证迭代器不失效。it 是 rbegin -> rend, 从右往左;而emplace_back是从左往右。

结果还是rbegin失效了。。

所以我就有点懵逼,问了一下同学,同学也说应该没问题,c++ primer里也有说明:

调试了一下,发现这个说法,对普通的iterator是对的,但是reserve_iterator(准确来讲是rbegin()返回的迭代器,比如代码里it)不一样,任何插入都会导致其失效。


调试:

源码里emplace_back无效iterator的地方:

 

it = v.rbegin(),实际it里面记录的是vector中end()返回的迭代器,放在其成员变量current里。

vector中的rbegin函数定义:

reserve_iterator的构造:

对于reserve_iterator的引用,++,--,都是对current操作:

显然,emplace_back会将之前的v.end()返回的迭代器内容无效,这就导致current无效了,因此,++it 出现异常。

 

 


https://stackoverflow.com/questions/40581249/how-to-use-vectortreverse-iterator-with-one-element 这里与David Scarlett的说法是一致的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值