函数功能:查找在父序列中最后匹配的子序列.
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;
}
find_end详解
最新推荐文章于 2022-01-13 09:25:40 发布