【Q&A】去除stl vector中特定位置的多个元素续_remove算法初探

来源:互联网 发布:docker 跨主机网络 编辑:程序博客网 时间:2024/06/03 19:24

这个是上一篇“去除stl vector中特定位置的多个元素”姊妹篇,有网友建议我用一下算法库中的remove和vector的函数erase。实现了一下,代码如下:

bool Play::RmSomeElementsInVec3 (vector<int> & NumVec, int iVal){if (NumVec.empty())return false;vector<int>::iterator pNewEnd = remove (NumVec.begin(), NumVec.end(), iVal);NumVec.erase (pNewEnd, NumVec.end());return true;}

代码很少,能够很方便的删除vector中等于iVal的元素。当vector中存储的是struct或者class等稍微复杂的数据结构的时候,也可以通过重新定义“等于”的语义——重载“==”符号——来自定义所需的“删除标准”,从而删除符合特定需求的元素。

debug进入remove算法,看到源代码如下:

// TEMPLATE FUNCTION removetemplate<class _FwdIt,class _Ty> inline_FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val){// remove each matching _Val 找到语义上等于_Val的元素_First = find(_First, _Last, _Val);if (_First == _Last)  // 序列中不存在这个元素return (_First);// empty sequence, all doneelse  // 序列中存在这个元素,在这个元素之后(++_First)对序列调用unchecked_remove_copy{// nonempty sequence, worth doing_FwdIt _First1 = _First;// 调用unchecked_remove_copy来移动vector中的元素return (_STDEXT unchecked_remove_copy(++_First1, _Last, _First, _Val));}}

上面的中文注释是自己加的。又debug进unchecked_remove_copy去看看,它最终是调用_Remove_copy来完成任务,代码实现如下:

// TEMPLATE FUNCTION remove_copytemplate<class _InIt,class _OutIt,class _Ty> inline_OutIt _Remove_copy(_InIt _First, _InIt _Last,_OutIt _Dest, const _Ty& _Val, _Range_checked_iterator_tag){// copy omitting each matching _Val_DEBUG_RANGE(_First, _Last);_DEBUG_POINTER(_Dest);for (; _First != _Last; ++_First)if (!(*_First == _Val)) // 不知道这里为什么不用“!=”直接判断?*_Dest++ = *_First;return (_Dest);}

基本原理同我们上一篇中的一样,不过写的更加简洁。算法时间复杂度也是O(n),不过没有用辅助存储空间。


总结一下,对比两种方法:

1. 算法时间复杂度都是O(n),不过remove+erase方法代码简洁,并且没有用辅助存储空间效率更高;不过只方便对“等于”语义的元素做过滤,并且需要显示定义等于语义,灵活度有待商榷。

2. 上一篇软文方法,实际上把库函数根据自己需要实现了一下,需要辅助存储空间,不过不局限于等于语义,稍灵活。


先写到这里。


原创粉丝点击