函数功能:查找在父序列中最后匹配的子序列. 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; }