ex9.26: 定义int ia[] = {0,1,1,2,3,5,8,13,21,55,89};将数组ia 拷贝到一个vector 和一个list中,使用单迭代器版本的erase函数从list删除奇数元素,从vector删除偶数元素。
知识点考查:删除元素
c.pop_front(); //删除首元素;vector/string 不支持此成员函数
c.pop_back(); //删除尾元素;
//forward_list不支持 递减--,back(),pop_back()
c.erase(p);
//删除迭代器所指定的元素,返回一个指向被删元素之后元素的迭代器,若p指向尾元素,则返回尾后迭代器,若p是尾后迭代器,则函数行为未定义;
c.erase(b,e);
//删除迭代器b和e所指定范围内的元素,返回一个指向最后一个被删元素之后元素的迭代器,若e本身就是尾后迭代器,则函数也返回尾后迭代器
b=c.erase(b,e);//调用后,b==e,
c.clear();//删除c中所有元素,返回void
c.erase(c.begin(),c.end());//等价于c.clear();
代码如下:
#include<iostream>
#include<vector>
#include<list>
using namespace std;
int main()
{
int ia[] = {0,1,1,2,3,5,8,13,21,55,89};
vector<int>vint;
list<int>lint;
for (int i=0;i<sizeof(ia)/sizeof(int);i++)//int型数组长度表示 sizeof(ia)/sizeof(int)
{
vint.push_back(ia[i]);
lint.push_back(ia[i]);
}
auto it1 = vint.begin();
auto it2 = lint.begin();
while (it1 != vint.end())
{
if (!(*it1 % 2))//若为偶数
it1=vint.erase(it1);//it1自动指向所删除元素之后的元素
else
++it1;
}
while (it2 != lint.end())
{
if (*it2 % 2)//若为奇数
it2 = lint.erase(it2);
else
++it2;
}
for (auto i : vint)
cout << i<< " ";
cout << endl;
for (auto j : lint)
cout << j << " ";
cout << endl;
return 0;
}
ex9.27: 编写程序,查找并删除forward_list中的奇数元素。
知识点考查:forward_list
**//-------forward_list中的插入删除操作-----------**
lst.before_begin()//返回指向链表首元素之前不存在的元素的迭代器
lst.cbefore_begin()//返以一个const-iterator
lst.insert_after(p,t)//在迭代器p之后的位置插入元素t
lst.insert_after(p,n,t)//在迭代器p之后的位置插入n个元素t
lst.insert_after(p,b,e)//在迭代器p之后的位置插入迭代器[b e)之间元素
lst.insert_after(p,il)//在迭代器p之后的位置插入花括号列表il中的元素
emplace_after(p,args)//使用args在p指定的位置之后创建一个元素。返回一个指向这个新元素的迭代器。若p为尾后迭代器,则函数未定义。
lst.erase_after(p)//删除p指向的位置之后的元素,返回一个被删除元素之后元素的迭代器
lst.erase_after(b,e)//删除从[b,e)之间的元素,返回一个被删除元素之后元素的迭代器
/*注意:
forward_list不支持 递减--,push_back, pop_back, back 等操作
未定义 insert, emplace, erase,
而定义 insert_after, emplace_after, erase_after,
*/
代码如下:
#include<iostream>
#include<forward_list>
using namespace std;
int main()
{
forward_list<int>flint = {0,1,2,3,4,5,6,7,8,9};
auto prev = flint.before_begin();//首前元素
auto curr= flint.begin();//首元素
while (curr!=flint.end())
{
if (*curr % 2)//若是奇数
{
curr = flint.erase_after(prev);//删除prev的下一个元素,即删除当前元素,返回下一个元素
}
else
{
prev = curr;
++curr;
}
}
for (auto i : flint)
cout << i << " ";
cout << endl;
return 0;
}
ex9.28: 编写函数,接受以恶搞forward_list和两个string共三个参数。函数应在链表中查找第一个string,并将第二个string插入到紧接着第一个string之后的位置。若第一个string未在链表中,则将第二个string插入到链表末尾。
代码如下:
#include<iostream>
#include<forward_list>
#include<string>
using namespace std;
void insert(forward_list<string>& fls2, const string &s1, const string &s2)
{
auto curr = fls2.begin();
auto prev = fls2.before_begin();
for (; curr != fls2.end(); prev = curr++)
{
if (*curr == s1)
{
fls2.insert_after(curr, s2);
return;
}
}
fls2.insert_after(prev, s2);
}
int main()
{
//forward_list<string>fls = { "a","ab","abc","abcd" };
forward_list<string>fls = { "a","abc","abcd" };
insert(fls,"ab","ab2");
string str;
for (auto str : fls)
cout << str << " ";
cout << endl;
return 0;
}
ex9.29:
//考查知识点:resize()来增大或缩小容器;
/*
list<int>ilist(10,42);//10个int,每个值都是42
ilist.resize(15);//在ilist的末尾添加5个0
ilist.resize(25,-1);//在ilist末尾添加10个-1
ilist.resize(5);//从ilist末尾删除20个元素
*/
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec(25, 1);
int i;
for (auto i:vec)
cout << i << " ";
cout << endl;
cout << endl;
vec.resize(100);//将75个0元素添加到vector的末尾
for (auto i : vec)
cout << i << " ";
cout <<endl;
cout << endl;
vec.resize(10); //从vector末尾删除90个元素
for (auto i : vec)
cout << i << " ";
cout << endl;
return 0;
}
ex9.31: 实现循环程序,删除偶数数值元素,复制奇数数值元素。
(1)vector、string、deque实现
添加或者删除vector、string、deque元素的循环元素必须考虑迭代器,引用,指针可能失效的问题;
程序必须保证每个循环步中都更新迭代器、引用或指针;
若循环中调用的是insert 或erase,那么更新迭代器很容易,因为这些操作都返回迭代器;
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto iter = vi.begin();//调用begin而不是cbegin,因为要改变vi
while (iter != vi.end())
{
if (*iter % 2)
{
iter = vi.insert(iter, *iter);//复制当前奇数元素
iter+=2;//向前移动迭代器,跳过了当前元素已经插入到它之前的元素
}
else
iter = vi.erase(iter);//删除偶数元素,返回的iter指向被删元素的下一个元素
}
for (auto i : vi)
cout << i << " ";
return 0;
}
(2) list实现
当向容器中添加或者删除元素时,对于list和forward_list,指向容器的迭代器(包括尾后迭代器和首前迭代器)、指针和引用仍有效。
#include <iostream>
#include <list>
using namespace std;
int 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);
advance(iter, 2);//类比iter+=2;但list不支持递增++运算符
}
else
iter = vi.erase(iter);
}
for (auto i : vi)
cout << i << " ";
return 0;
}
(3) forward_list实现
#include <iostream>
#include <forward_list>
using namespace std;
int main()
{
forward_list<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto iter = vi.begin(), prev = vi.before_begin();
while (iter != vi.end())
{
if (*iter % 2)
{
iter = vi.insert_after(prev, *iter);
advance(iter, 2);//注意比较
advance(prev, 2);//注意比较
}
else
iter = vi.erase_after(prev);
}
for (auto i : vi)
cout << i << " ";
return 0;
}
——————————————
ex9.32-9.36较简单,略过!
——————————————