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

这个是上一篇“去除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 remove
template<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 done
	else  // 序列中存在这个元素,在这个元素之后(++_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_copy
template<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. 上一篇软文方法,实际上把库函数根据自己需要实现了一下,需要辅助存储空间,不过不局限于等于语义,稍灵活。


先写到这里。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值