【Q&A】去除stl vector中特定位置的多个元素
来源:互联网 发布:linux如何安装java8 编辑:程序博客网 时间:2024/05/10 19:18
我个人常用stl vector来构建基础数据结构,实现一些算法。有时候会有这样的需求,就是我要删除满足某些条件的vector中的元素,例如:删除所有大于零的元素。这就需要遍历整个数组,找到这些元素,并且删除。有两种策略。直观的一种是在遍历的过程中,判断当前元素是否符合删除条件,如果符合,则调用vector的erase函数进行删除,注意这时候数组内容发生变化,iterator原则上失效,会影响到遍历过程。
不过我更在意这种策略的效率。调用erase函数的时候,所有当前删除位置之后的元素都向前移动一个位置。当数组元素是n个、待删除元素是m个的时候,算法复杂度是O(mn)。有点高,不利索。
另一种策略,就是今天列出来的,简单地说就是用空间来换时间。用一个n大小的vector存放0-1变量,1表示目标vector的这个位置的元素要删除,0表示要保留。同时遍历目标vector和这个标志vector,一次性删除所有要删除的元素。在时间上,因为在生成标志vector的时候需要遍历目标vector,在删除的时候,又要遍历一遍,所以总共遍历两遍,复杂度是O(2n)=O(n)。当待删除元素数目比较大的时候,这个算法还是比较有效率的。需要注意的是:1. 在删除过程中要同时遍历两个vector;2. 对于目标vector,需要维护两个下标,一个是遍历的当前位置下标,一个是写元素位置下标。
核心代码如下:
bool RmSomeElementsInVec (vector<int> & NumVec, vector<bool> & FlagVec){int iSize = (int)NumVec.size(); //目标数组大小if (iSize != (int)FlagVec.size()) //防御性代码return false;int iWritePos = 0; // 写位置下标,数组后续元素不断向前移动,这个是下一个要移动到的位置for (int iIterPos = 0; iIterPos < iSize; iIterPos++){if (!FlagVec.at(iIterPos)) // flag是0,表示保留当前位置的元素在数组中{if (iWritePos != iIterPos) // 将该元素移动到正确的位置上,同时避免在同一个位置上写操作,以提高效率NumVec.at (iWritePos) = NumVec.at (iIterPos);iWritePos++;}}if (iSize != iWritePos) //缩减数组大小到实际大小NumVec.resize (iWritePos);return true;}
写个程序做了两个假的输入数组NumVec和FlagVec,用来测试上面的代码,测试通过。代码如下:
void InitNumVecAndFlagVec (vector<int> & NumVec, vector<bool> & FlagVec){for (int i=0; i<1000; i++){NumVec.push_back (Array[i]);if (0 == i%2)FlagVec.push_back (1);elseFlagVec.push_back (0);}}
只保留偶数位置上的元素。Array是一个已经初始化好的数组,大小是1000。
还有更进一步的做法。如果生成n大小的flag vector比较浪费空间的话,可以只把需要删除的位置记录下来,记录到一个小于n的vector中。在删除的过程中,类似上面的过程,同时遍历两个vector,进行元素删除,代码如下:
bool RmSomeElementsInVec2 (vector<int> & NumVec, vector<int> & PosVec){int iNumSize = (int)NumVec.size ();if (0 == iNumSize)return false;int iPosSize = (int)PosVec.size();if (0 == iPosSize)return true;for (int i=0, j=0, iWritePos=0; i<iNumSize, j<iPosSize; ){if (i < PosVec.at(j)){if (i != iWritePos)NumVec.at (iWritePos) = NumVec.at (i);i++;iWritePos++;}else if (i == PosVec.at (j)){i++;j++;}elsecerr << "Never get here" << endl;}return true;}
由于遍历的两个vector长度不一样,就需要多一个下标变量。思路和上面的差不多,我就没有补充注释。同样,伪造了NumVec和PosVec,用来测试,代码如下:
void InitNumVecAndPosVec (vector<int> & NumVec, vector<int> & PosVec){for (int i=0; i<1000; i++){NumVec.push_back (Array[i]);if (0 == i%2)PosVec.push_back (i);}}
测试通过。
- 【Q&A】去除stl vector中特定位置的多个元素
- 【Q&A】去除stl vector中特定位置的多个元素续_remove算法初探
- 【Q&A】stl容器去除重复的元素
- 关于STL容器中vector特定元素的删除问题
- vector中特定元素的删除
- vector中特定元素的删除
- vector中去除重复的元素
- STL-去除list中重复的元素
- STL中Vector元素的删除
- STL中vector元素的一些操作方法
- matlab-高数 找到集合中特定元素的位置
- List数组去除特定元素的方法
- C++中vector删除指定位置的元素
- STL中map/vector的删除元素操作
- 在vector中查找元素及其位置
- C++学习之vector重复元素的去除和求vector中最大最小元素及其索引
- STL中vector删除一个元素
- java 字符串中去除特定的字符
- 为PB 的TreeView实现同步选择
- 发布一下最近做的一个应用-口语狂
- HDU 2571 命运
- 函数的按引用返回与按地址返回
- 紫薇花开的季节(二)
- 【Q&A】去除stl vector中特定位置的多个元素
- Ubuntu下VMware Tools安装及常用软件的安装
- Ubuntu系统及软件安装之一系统安装
- zoj3513 Human or Pig----P/N分析 博弈
- windowsserver查看服务器端口占用查询命令以及服务器连接数
- Linux内存管理 Slab分配器(二:初始化)
- Firebird获取表字段及定义
- 科技博文开篇自序
- stm32F103模拟I2C读写24c02