因醜數問題聯想到的STL迭代器失效問題·vector

    今天寫一個醜數的程序,一開始用的迭代器表示位置,寫出了這個
int GetUglyNumber_Solution(int index) {
	if (index <= 0) return 0;//返回錯誤信息
	vector<int> uglyNums;
	uglyNums.push_back(1);
	//定義三個迭代器Tx,分別表示第一個乘以x後大於當前最大丑數的元素的位置
	vector<int>::iterator T2 = uglyNums.begin();
	vector<int>::iterator T3 = T2;
	vector<int>::iterator T5 = T2;
	while (uglyNums.size() < index) {
		while (*T2 * 2 <= uglyNums.back()) { ++T2; }
		while (*T3 * 3 <= uglyNums.back()) { ++T3; }
		while (*T5 * 5 <= uglyNums.back()) { ++T5; }
		int min = *T2 * 2;
		int U3 = *T3 * 3;
		int U5 = *T5 * 5;
		if (U3 < min) min = U3;
		if (U5 < min) min = U5;
		uglyNums.push_back(min);//這裏會使得迭代器失效
	}
	return uglyNums.back();
}

然後調試的時候發現不對啊,第二次循環的時候,三個迭代器都失效了。然後想起,vector的內存分配機制

1.當插入(push_back)一個元素後,end操作返回的迭代器肯定失效。
2.當插入(push_back)一個元素後,capacity返回值與沒有插入元素之前相比有改變,則需要重新加載整個容器,此時begin和end操作返回的迭代器都會失效。

3.當進行刪除操作(erase,pop_back)後,指向刪除點的迭代器全部失效;指向刪除點後面的元素的迭代器也將全部失效。

對於vector而言,添加和刪除操作可能使容器的部分或者全部迭代器失效。vector元素在內存中是順序存儲,如果當前容器中已經存在了10個元素,現在又要添加一個元素到容器中,但是內存中緊跟在這10個元素後面沒有一個空閒空間,而vector的元素必須順序存儲一邊索引訪問,所以我們不能在內存中隨便找個地方存儲這個元素。於是vector必須重新分配存儲空間,用來存放原來的元素以及新添加的元素:存放在舊存儲空間的元素被複制到新的存儲空間裏,接着插入新的元素,最後撤銷舊的存儲空間。這種情況發生,一定會導致vector容器的所有迭代器都失效。我們看到實現上述所說的分配和撤銷內存空間的方式以實現vector的自增長性,效率是極其低下的。爲了使vector容器實現快速的內存分配,實際分配的容器會比當前所需的空間多一些,vector容器預留了這些額外的存儲區,用來存放新添加的元素,而不需要每次都重新分配新的存儲空間。你可以從vector裏實現capacity和reserve成員可以看出這種機制。capacity和size的區別:size是容器當前擁有的元素個數,而capacity則指容器在必須分配新存儲空間之前可以存儲的元素總數。

int GetUglyNumber_Solution(int index) {
	if (index <= 0) return 0;//返回錯誤信息
	vector<int> uglyNums;
	uglyNums.push_back(1);
	int T2, T3, T5;
	T2 = T3 = T5 = 0;
	while (uglyNums.size() < index) {
		while (uglyNums[T2] * 2 <= uglyNums.back()) { ++T2; }
		while (uglyNums[T3] * 3 <= uglyNums.back()) { ++T3; }
		while (uglyNums[T5] * 5 <= uglyNums.back()) { ++T5; }
		int min = uglyNums[T2] * 2;
		int U3 = uglyNums[T3] * 3;
		int U5 = uglyNums[T5] * 5;
		if (U3 < min) min = U3;
		if (U5 < min) min = U5;
		uglyNums.push_back(min);
	}
	return uglyNums.back();
}
皮這一下我很開心

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章