练习9.27:编写程序,查找并删除forward_list<int>中的奇元素。
编写代码之前,先介绍一下特殊的forward_list操作。
由于forward_list是单向链表,不能像其它容器那样指定删除某个元素。只能指定删除某个元素的后一个元素,这样才方便在单向链表中实现。基于此,定义了如下单向链表操作函数:(代替原有的insert erase emplace)
lst.before_begin() //返回指向链表首元素之前的位置的迭代器 此迭代器不指向任何元素
lst.cbefore_begin() //所以不能解引用
lst.insert_after(p,t) //p:迭代器 插入位置为此位置之后的位置
lst.insert_after(p,n,t) //t:一个对象 待插入的对象
lst.insert_after(p,b,e) //n:个数 插入的对象的个数 b e:待复制迭代器的起始位置
lst.insert_after(p,il) //il 要插入对象的列表
//以上代码均是返回一个指向最后一个插入元素的迭代器
emplace_after(p,args) //使用args在p指定的位置后面创建一个元素。返回一个指向这个新元素的迭代器。
lst.erase_after(p) //删除p之后的一个元素 或者删除b的下一个元素到e(不包含e)的元素。
lst.erase_after(b,e)
//以上代码返回一个被删除的元素的下一个元素的迭代器。
//所有迭代器均不能是尾后迭代器 如果是尾后迭代器 则行为未定义
forward_list<int> ss = { 1, 2, 3, 4, 5, 6 };
auto prev = ss.before_begin();
auto curr = ss.begin();
while (curr != ss.end()){
if (*curr % 2 == 0)
curr = ss.erase_after(prev);
else{
prev = curr;
curr++;
}
}
定义了两个迭代器 一个是位置前 一个是位置后 一个负责解引用取值 一个负责删除元素。
用erase_after()之后,将返回一个被删元素之后的一个元素的迭代器。将其赋值给当前迭代器变量,prev的值不变。
练习9.28:编写函数,接受一个forward_list<string>和两个string共3个参数。函数应在链表中查找第一个string,并将第二个string插入到紧接着第一个string之后的位置。若第一个string未在链表中,则将第二个string插入到链表末尾。
void MyInsert(forward_list<string> &lst, string s1, string s2){
auto prev = lst.before_begin();
auto curr = lst.begin();
while (curr != lst.end()){
prev = curr;
if (*curr == s1){
curr = lst.insert_after(curr, s2);
break;
}
else
curr++;
}
if (curr == lst.end())
lst.insert_after(prev, s2);
}
以上代码 insert返回的是插入的最后一个元素的迭代器。