1. 程式人生 > >C++Primer第五版 第九章習題答案(31~40)

C++Primer第五版 第九章習題答案(31~40)

31:知識點1:容器的改變可能會使迭代器失效,插入和刪除各有其相關的規則,P315.

知識點2:必須保證每次改變容器的操作之後都正確的重新定位迭代器的操作

知識點3:呼叫erase()之後,其返回的迭代器指向的是序列中的下一個元素,其返回的迭代器可以用來更新

知識點4:向容器插入元素後,對於list和forward_list,指向容器的迭代器、指標、引用皆有效

對於list

advance(iter, 2);

對於forward_list

#include<iostream>
#include<forward_list>
using namespace std;
void main()
{
	forward_list<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto prev = vi.before_begin();
	auto curr = vi.begin();
	while (curr != vi.end())
		if (*curr % 2)
		{
			curr = vi.insert_after(prev, *curr);    //返回迭代器,指向新插入元素
			prev = ++curr;
			++curr;
		}
		else
			curr = vi.erase_after(prev);
	for (auto a : vi)
		cout << a << ends;
	cout << endl;
	system("pause");
}

32:首先明確運算子的順序:++高於*解引用符號。

       分析:對於容器vi = {0,1,2,3,4,5,6,7,8,9}; iter = vi.insert(iter,*iter ++); 後置++雖然優先順序高於解引用*,但是iter是拿遞增之前的迭代器去解引用,所以第一次的插入操作vi.insert(iter,*iter ++)中,第二個引數*iter ++ 的結果是1,而第一個引數iter則為遞增之後的迭代器(此時指向2),故應該是在2之前插入1。 但是,返回的是插入元素的迭代器,故,iter又重新指向0,1,1,2,3,4,5,6,7,8,9的第二個1。這樣之後的操作會無限迴圈的再2前面插入1。因此需要手動移動迭代器,程式碼如下:

#include<iostream>
#include<list>
using namespace std;
void main()
{
	list<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto iter = vi.begin();
	while (iter != vi.end())
		if (*iter % 2)
		{
		iter = vi.insert(iter, *iter++);
		++iter;
		}
		else
			iter = vi.erase(iter);
	for (auto a : vi)
		cout << a << ends;
	cout << endl;
	system("pause");
}

33:知識點:不要儲存end返回的迭代器,因為你對容器的操作會使得這個迭代器失效。(vector,string,deque)

程式會崩潰,因為begin迭代器的值在插入一個元素之後已經失效。

34:老生常談的問題了,insert()返回的迭代器是指向新插入元素的,如若進行插入元素,需要加兩次才能跳過當前元素。

**************************************未完待續***********************************************