练习9.27:编写程序,查找并删除forward_list<int>中的奇数元素。
解答:
#include<iostream>
#include<forward_list>
using std::forward_list;using std::cout;using std::endl;
int main()
{
forward_list<int> f{1,2,3,4,5,6,7,8,9,0};
auto prev = f.before_begin();
auto curr = f.begin();
while(curr != f.end())
{
if(*curr %2 != 0)
curr = f.erase_after(prev);
else
{
prev = curr;
++curr;
}
}
for(auto i:f)
cout<<i<<" ";
cout<<endl;
return 0;
}
练习9.28:编写函数,接受一个forward_list<string>和两个string共三个参数。函数应该在链表中查找第一个string,并将第二个string插入到紧接着第一个string之后的位置。若第一个string未在链表中,则将第二个string插入到链表末尾。
解答:
void insert(forward_list<string> &flist,string find,string insert)
{
auto prev = flist.before_begin();
auto curr = flist.begin();
while(curr != flist.end())
{
if(*curr==find)
flist.insert_after(curr,insert);
else
{
prev = curr;
++curr;
}
}
flist.insert_after(prev,insert);
}
练习9.29:假定vec包含25个元素,那么vec.resize(100)会做什么?如果接下来调用vec.resize(10)会做什么?
解答:
vec.resize(100); // 增加75个值为0的元素在vec的尾部;
vec.resize(10); //在vec的尾部删除90个元素;
练习9.30:接受单个参数的resize版本对元素类型有什么限制(如果有的话)?
解答:
如果容器保存的是类类型元素,且resize向容器中添加新元素,则我们必须提供初始值,或者元素类型必须提供一个默认构造函数。
练习9.31:第316页中删除偶数值元素并复制奇数值元素的程序不能用于list和forward_list。为什么?修改程序,使之也能用于这些类型。
解答:
list和forward_list不支持运算符操作;
//list
#include<iostream>
#include<list>
using std::list;using std::endl;using std::cout;using std::advance;
int main()
{
list<int> ilst{0,1,2,3,4,5,6,7,8,9};
auto iter = ilst.begin();
while(iter != ilst.end())
{
if(*iter%2)
{
iter = ilst.insert(iter, *iter);
advance(iter,2);
}
else
iter = ilst.erase(iter);
}
for(auto i:ilst)
cout<<i<<" ";
cout<<endl;
return 0;
}
//forward_list
#include<iostream>
#include<forward_list>
using std::forward_list;using std::endl;using std::cout;using std::advance;
int main()
{
forward_list<int> flst{0,1,2,3,4,5,6,7,8,9};
auto iter = flst.begin();
auto prev = flst.before_begin();
while(iter != flst.end())
{
if(*iter%2)
{
iter = flst.insert_after(prev, *iter);
advance(iter,2);
advance(prev,2);
}
else
iter = flst.erase_after(prev);
}
for(auto i:flst)
cout<<i<<" ";
cout<<endl;
return 0;
}
练习9.32:在第316页的程序中,向下面语句这样调用insert是否合法?如果不合法,为什么?
iter = vi.insert(iter, *iter++);
解答:
这种语句是非法的,因为当输入函数插入数据时,iter的值可能是原始值或原始值+1,甚至是其它值,这依赖于编译器。
练习9.33:在本节最后一个例子中,如果不将insert的结果赋予begin,将会发生什么?编写程序,去掉此赋值语句,验证你的答案。
解答:
程序会崩溃,因为插入元素后迭代器失效,继续操作迭代器是未定义操作,会导致程序崩溃。
#include<iostream>
#include<vector>
using std::vector;using std::endl;using std::cout;
int main()
{
vector<int> vec{0,1,2,3,4,5,6,7,8,9};
auto begin = vec.begin();
while(begin != vec.end())
{
++begin;
/* begin = */ vec.insert(begin,42);
++begin;
}
for(auto i:vec)
cout<<i<<" ";
cout<<endl;
return 0;
}
练习9.34:假定vi是一个保存int的容器,其中有偶数值也有奇数值,分析下面循环的行为,然后编写程序验证你的分析是否正确。
iter = vi.begin;
while(iter != vi.end())
if(*iter % 2)
iter = vi.insert(iter, *iter);
++iter;
解答:
会无限循环,因为++iter在while的外面,iter的值改变不了,导致无限循环。
#include<iostream>
#include<vector>
using std::vector;using std::endl;using std::cout;
int main()
{
vector<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;
}
++iter;
}
for(auto i:vi)
cout<<i<<" ";
cout<<endl;
return 0;
}