1.引言

以下代码有什么问题,如何修改?

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int>);//传引用不妥!!
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//删除array中的所有的6
vector<int>::iterator itor;
vector<int>::iterator itor2;
itor=array.begin();
for (itor=array.begin();itor!=array.end();itor++;)
{
if (6==*itor)
{
itor2=itor;
array.erase(itor2);
}
}
print(array);
return 0;
}
void print(vector<int> v)
{
cout<<"\nvector size is: "<<v.size()<<endl;
}

2.vector中erase源码

这段代码运行后容量只减小1,具体问题出在哪不知道。先看一下erase的源码。

iterator erase(iterator position)
{
if (position + 1 != end()) //若position不是指向最后一个元素
copy(position + 1, finish, position); //运用的是copy,将删除位置的元素向后移动
--finish;//vector中finish所指位置为end()返回值
destroy(finish);
return position;
}
iterator erase(iterator first, iterator last) //允许last在first之前,后果自负
{
iterator i = copy(last, finish, first);
destroy(i, finish);
finish = finish - (last - first);
return first;
}

现在知道了,如果这时删除一个元素之后,itor已经指向下一个元素,所以再调用itor++,那么连续的2个6就只能删除前一个。

所以以上的for循环可以改为:

for (itor=array.begin();itor!=array.end();itor++;)
{
if (6==*itor)
{
itor2=itor;
array.erase(itor2);
itor--;
}
}

3.remove源码

但是这样的代码可读性欠佳,还有一种改法就是更加规范的简洁的操作:调用算法remove,之后再进行erase。

此时将for循环替代为:array.erase(remove(array.begin().array.end(),6),array.end());当然这个时候要包含头文件<algorithm>。

为什么要删除,remove返回后的迭代器到vector末尾的元素呢?看remove算法源码。

remove操作移除[first,last)之中所有与value相等的元素。这一算法并不真正从容器中删除那些元素(换句话说容器的大小并没有改变),而是将每一个不与value相等的元素轮番赋值给first之后的空间。返回值ForwardIterator标示出重新整理后的最后元素的下一个位置。例如序列{0,1,0,2,0,3,0,4},如果执行remove删除0,则结果是{1,2,3,4,0,3,0,4},返回值ForwardIterator指向第5个元素。所以如果要删除那些残余元素可以使用erase的两迭代器版本。源码如下:

tamplate<class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value)
{
first=find(first, last, value);//找到第一个相等的元素
ForwardIterator next = first;//以next标示出来
//以下利用“remove_copy()允许新旧容器重叠”的性质,进行移除操作
//并将结果置于原容器中
return first == last ? first : remove_copy(++next,last,first,value);
}

remove_copy并不改变原来的容器,只是将所要删除的值删除后,将新容器存储在result迭代器所指的位置处。

tamplate<class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value)
{
for(;first != last;++first)
if(*first != value)    //如果不相等
{
*result = *first;  //赋值给新容器
++result;
}
return result;
}

当然remove函数也有仿函数版本的remove_if,remove_copy_if。

4.list中的remove和erase操作

list中的erase:

iterator erase(iterator position)
{
link_type next_node = link_typr(position.node->next);
link_type prev_node = link_typr(position.node->prev);
prev_node->next = next_node;
next_node->prev = prev_node;
destroy_node(position.node);
return iterator(next_node);
}

remove是算法库中的一个算法,但是list的结构使用这种remove算法时效率低下。根据list的结构,标准库专门为list设计了remove操作(其他容器是没有的)。

template<class T, calss Alloc>
void list<T,Alloc>::remove(const T& value)
{
iterator first = begin();
iterator last = end();
while(first != last)
{
iterator next = first;
++next;
if(*first == value) erase(first);
first = next;
}
}

5.deque、set、map的erase操作

待补充…………………..

erase和remove相关推荐

  1. vector删除元素erase与remove区别

    vector删除元素可用erase与remove,但是使用erase后vector本身size()随之变化,而使用remove后vector本身size()并没有变化,只有迭代器指向变了!!!所以使用 ...

  2. c语言remove命令和erase,详解C++ list中erase与remove函数的使用

    C语言中的erase与remove函数一直让小编很迷糊,因为他们的功能都是一样的,本文是详解C++ list中erase与remove函数的使用方法,接下来爱站技术频道小编带你一起来了解吧! eras ...

  3. C++ std::remove/std::remove_if/erase用法探讨

    ​std::remove 不会改变输入vector/string的长度.其过程相当于去除指定的字符,剩余字符往前靠.后面的和原始字符保持一致.​ 需要注意的是,remove函数是通过覆盖移去的,如果容 ...

  4. C++ remove、remove_copy、remove_if和remove_copy_if函数使用详解

    如果不知道具体的场景,即元素保存在什么样的容器中,是不能从序列中移除元素的.因此,"移除元素的"算法也无法做到这一点,它们只会重写被选择的元素或者忽略复制的元素.移除操作不会改变被 ...

  5. vector erase使用

    文章目录 vector erase原型 删除普通元素 删除指针元素 remove与erase混合使用 vector erase原型 // erase的函数原型有两种形式 iterator erase( ...

  6. Effective STL 50条有效使用STL的经验笔记

    Scott Meyers大师Effective三部曲:Effective C++.More Effective C++.Effective STL,这三本书出版已很多年,后来又出版了Effective ...

  7. 【C++】Effective STL:50条有效使用STL的经验

    第一条:慎重选择容器类型 1.C++容器:先混个眼熟 序列容器:array.vector.string.deque.list.forward_list 有序关联容器:set.map.multiset. ...

  8. 【C++】C++11 STL算法(二):修改序列的操作(Modifying sequence operations)

    目录 一.copy.copy_if 1.原型: 2.说明: 3.官方demo 二.copy_n 1.原型: 2.说明: 3.官方demo 三.copy_backward 1.原型: 1.说明: 1.官 ...

  9. 如何在C ++中从容器中删除元素

    How to remove elements from container is a common C++ interview question, so you can earn some brown ...

最新文章

  1. CSS Sprites图片拼合生成器实现思路
  2. 洛谷 P1690 贪婪的Copy
  3. 编译Android 4.0 ICS注意事项
  4. wxPython多线程界面卡死或在不同平台崩溃问题
  5. 神经网络 卷积神经网络_如何愚弄神经网络?
  6. pheatmap, gplots heatmap.2和ggplot2 geom_tile实现数据聚类和热图plot
  7. 求数组所有区间最大值减去最小值之差的和(贝壳笔试题)
  8. display属性值
  9. FFT【快速傅里叶变换】FWT【快速沃尔什变换】
  10. zepto(适用于移动端开发)
  11. android addr2line使用
  12. 苹果企业开发者账号证书申请(保姆级)
  13. Android常用开源项目
  14. seaborn画分组箱线图
  15. 为远程群晖NAS配置固定的公网URL地址 1/2
  16. js将数字转换为汉字
  17. 股票查询接口功能是什么?
  18. JAVA开发与运维(JavaWeb测试环境搭建)
  19. 小白成长之路-linux定时任务cron和crontab
  20. ## 大一java课程设计_航班查询系统(我是小白)

热门文章

  1. 阿里云服务器SSL不可用
  2. 飞猪双11成绩单背后 藏了什么玄机
  3. html制作地球自转,利用CSS3实现地球自转
  4. 有可控冷热水隔板的储水式电热水器
  5. 1259_STM32CubeProgrammer的简单使用
  6. [ASP.NET] 结合Web API在OWIN下实现OAuth
  7. NTC电阻短路(高温)电池未停止充电分析
  8. ECHARTS的基本使用:柱状图、折线图、饼图等
  9. MySQL 三星索引
  10. 国家药品监督管理局药品审评中心—重点功能介绍