find_end详解

41 篇文章 0 订阅
39 篇文章 2 订阅
函数功能:查找在父序列中最后匹配的子序列.
find_end这个函数比较特殊一点,说起特殊并不是指其功能的特殊,而是其命名的特殊.
我们知道find系列算法是查找指定值的函数(单个值),而search系列则是查找”子系列”算法.但是Nicolai M.Josuttis在书里面也介绍到了原因:它说是因为这些算法并非早起STL的部分.这可能就是需要C++标准委员会商榷的一部分了.但是话又说回来,如果按照search系列(参考: http://blog.csdn.net/yuanweihuayan/article/details/7536737)的命名,之前曾今使用过的程序未免会有些混乱的时候.
而更奇怪的是,我在vs2010上看到的实现版本更是让我大吃一惊.居然是利用顺序比较的方法了查找子系列.完全没有使用一点技巧.
	我们其实可以利用反向迭代器来加快完成这项工作的.而且在查找初始化的时候,应该是从父序列的parentSize – childSize位置开始.这样就完全提高了效率.
// TEMPLATE FUNCTION find_end
template<class _FwdIt1,
	class _FwdIt2,
	class _Diff1,
	class _Diff2> inline
	_FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Diff1 *, _Diff2 *)
	{	// find last [_First2, _Last2) match
	_Diff1 _Count1 = 0;
	_Distance(_First1, _Last1, _Count1);
	_Diff2 _Count2 = 0;
	_Distance(_First2, _Last2, _Count2);
	_FwdIt1 _Ans = _Last1;

	if (0 < _Count2)//如果_Count2<0,就直接返回_Last1
		for (; _Count2 <= _Count1; ++_First1, --_Count1)
			{	// room for match, try it
			_FwdIt1 _Mid1 = _First1;
			for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1)
				if (!(*_Mid1 == *_Mid2))//如果两者不相等,则跳出内循环,继续外循环
					break;
else if (++_Mid2 == _Last2)//如果两者相等(从上面的if-else结构来
//看,下面就是non if部分),并且++_Mid2和_Last相等(说
//明内循环结束,一轮匹配完成),那么保存_Fist1到_Ans
//中,否则就是还没有完成全部内循环,由于运行了
//++_Mid2,所以内循环在很”隐蔽的”的情况继续.(即++)
					{	// potential answer, save it
					_Ans = _First1;
					break;
					}
			}
	return (_Ans);
	}

template<class _FwdIt1,
	class _FwdIt2> inline
	_FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2)
	{	// find last [_First2, _Last2) match
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	return (_Rechecked(_First1,
		_Find_end(_Unchecked(_First1), _Unchecked(_Last1),
			_Unchecked(_First2), _Unchecked(_Last2),
			_Dist_type(_First1), _Dist_type(_First2))));
	}
至于这里面用到的一些宏,这里就不再赘述,有兴趣的可以参考我上面列出的那篇文章.
其重载函数如下:
函数功能:查找在父序列中使得_Pred为真的最后匹配的子序列.
		// TEMPLATE FUNCTION find_end WITH PRED
template<class _FwdIt1,
	class _FwdIt2,
	class _Diff1,
	class _Diff2,
	class _Pr> inline
	_FwdIt1 _Find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *)
	{	// find last [_First2, _Last2) satisfying _Pred
	_Diff1 _Count1 = 0;
	_Distance(_First1, _Last1, _Count1);
	_Diff2 _Count2 = 0;
	_Distance(_First2, _Last2, _Count2);
	_FwdIt1 _Ans = _Last1;

	if (0 < _Count2)
		for (; _Count2 <= _Count1; ++_First1, --_Count1)
			{	// room for match, try it
			_FwdIt1 _Mid1 = _First1;
			for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1)
				if (!_Pred(*_Mid1, *_Mid2))//之前是_Mid1==_Mid2,现在当然是使得_Pred为真喽
					break;
				else if (++_Mid2 == _Last2)
					{	// potential answer, save it
					_Ans = _First1;
					break;
					}
			}
	return (_Ans);
	}

template<class _FwdIt1,
	class _FwdIt2,
	class _Pr> inline
	_FwdIt1 find_end(_FwdIt1 _First1, _FwdIt1 _Last1,
		_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
	{	// find last [_First2, _Last2) satisfying _Pred
	_DEBUG_RANGE(_First1, _Last1);
	_DEBUG_RANGE(_First2, _Last2);
	_DEBUG_POINTER(_Pred);
	return (_Rechecked(_First1,
		_Find_end(_Unchecked(_First1), _Unchecked(_Last1),
			_Unchecked(_First2), _Unchecked(_Last2), _Pred,
			_Dist_type(_First1), _Dist_type(_First2))));
	}
这里需要注意的一点是:_Pred的形式是 bool (*Pfun)( parm1,parm2 );(即返回值bool和参数个数两个).
举例:还是之前的那个例子.
template<typename T>
bool equal_three( T _value1,T _value2 )
{
	return _value1 == ++ _value2;
}
int main()
{
	vector<int> vecInt;
	vecInt.push_back( 2 );
	vecInt.push_back( 3 );
	vecInt.push_back( 5 );
	vecInt.push_back( 4 );
	vecInt.push_back( 5 );
	vecInt.push_back( 3 );
	vecInt.push_back( 5 );
	vecInt.push_back( 4 );
	vecInt.push_back( 3 );

	list<int> lstInt;
	lstInt.push_back( 2 );
	lstInt.push_back( 4 );
	lstInt.push_back( 3 );
	vector<int>::iterator iterFind = find_end( vecInt.begin(),vecInt.end(),lstInt.begin(),lstInt.end(),equal_three<int> );
	if ( iterFind != vecInt.end() )
	{
		copy( iterFind,iterFind + lstInt.size(),ostream_iterator<int>( cout," " ) );
		cout<<"\n"<<*(-- iterFind)<<endl;
	}
	cout<<"\n";
	iterFind = find_end( vecInt.begin(),vecInt.end(),lstInt.begin(),lstInt.end() );
	if ( iterFind != vecInt.end() )
	{
		copy( iterFind,iterFind + lstInt.size(),ostream_iterator<int>( cout," " ) );
	}
	system( "pause" );
	return 0;
}

template<typename T>
bool equal_three( T _value1,T _value2 )
{
	return _value1 == ++ _value2;
}
int main()
{
	vector<int> vecInt;
	vecInt.push_back( 2 );
	vecInt.push_back( 3 );
	vecInt.push_back( 5 );
	vecInt.push_back( 4 );
	vecInt.push_back( 5 );
	vecInt.push_back( 3 );
	vecInt.push_back( 5 );
	vecInt.push_back( 4 );
	vecInt.push_back( 3 );

	list<int> lstInt;
	lstInt.push_back( 2 );
	lstInt.push_back( 4 );
	lstInt.push_back( 3 );
	vector<int>::iterator iterFind = find_end( vecInt.begin(),vecInt.end(),lstInt.begin(),lstInt.end(),equal_three<int> );
	if ( iterFind != vecInt.end() )
	{
		copy( iterFind,iterFind + lstInt.size(),ostream_iterator<int>( cout," " ) );
		cout<<"\n"<<*(-- iterFind)<<endl;
	}
	cout<<"\n";
	iterFind = find_end( vecInt.begin(),vecInt.end(),lstInt.begin(),lstInt.end() );
	if ( iterFind != vecInt.end() )
	{
		copy( iterFind,iterFind + lstInt.size(),ostream_iterator<int>( cout," " ) );
	}
	system( "pause" );
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值