search算法相关细节存储在<algorithm>
中,以下贴出search的源码及其重载版本。
// TEMPLATE FUNCTION search
template<class _FwdIt1,class _FwdIt2> inline
_FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1,_FwdIt2 _First2, _FwdIt2 _Last2)
{ // find first [_First2, _Last2) match
return (_STD search(_First1, _Last1, _First2, _Last2,
equal_to<>()));
}
该版本中_First1
,_Last1
代表要查找的范围,通常是两个迭代器。而_First2
,_Last2
代表需要查找的特定元素区间,通常是指向另外一个容器的迭代器(分别指向首个元素和最后一个元素之后的位置),在返回语句中调用了它的重载版本一。
template<class _FwdIt1,class _FwdIt2,class _Pr> inline
_FwdIt1 search(_FwdIt1 _First1, _FwdIt1 _Last1,_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred)
{ // find first [_First2, _Last2) satisfying _Pred
_DEBUG_RANGE(_First1, _Last1);
_DEBUG_RANGE(_First2, _Last2);
_DEBUG_POINTER(_Pred);
return (_Rechecked(_First1, _Search(_Unchecked(_First1), _Unchecked(_Last1), _Unchecked(_First2), _Unchecked(_Last2), _Pred, _Dist_type(_First1), _Dist_type(_First2))));
}
这个版本引入了一个新的参数_Pred,由语义及作用猜测应该是一个谓词(predicate),在第一个版本中我们可以看到传入的实参谓词是equal_to<>()
,应该是用来判断查找容器和目标容器部分元素是否相等。_DEBUG_RANGE()
函数检查_First1
,_Last1
有无出现前者大于后者的情况。接下来在return语句中又调用了search的第二个重载版本,也是最核心的版本。
// TEMPLATE FUNCTION search WITH PRED
template<class _FwdIt1,class _FwdIt2,class _Diff1,class _Diff2,class _Pr> inline
_FwdIt1 _Search(_FwdIt1 _First1, _FwdIt1 _Last1,_FwdIt2 _First2, _FwdIt2 _Last2, _Pr _Pred, _Diff1 *, _Diff2 *)
{ // find first [_First2, _Last2) satisfying _Pred
_Diff1 _Count1 = 0;
_Distance(_First1, _Last1, _Count1);
_Diff2 _Count2 = 0;
_Distance(_First2, _Last2, _Count2);
for (; _Count2 <= _Count1; ++_First1, --_Count1)
{ // room for match, try it
_FwdIt1 _Mid1 = _First1;
for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, ++_Mid2)
if (_Mid2 == _Last2)
return (_First1);
else if (!_Pred(*_Mid1, *_Mid2))
break;
}
return (_Last1);
}
这个版本多了两个新的参数_Diff1 *
,_Diff2 *
,用来传入待查找容器和特定容器的元素类型。首先定义了两个计数器_Count1
和_Count2
分别用来存储两个容器的大小。接着运用双重for循环,在内部定义_Mid1
和_Mid2
分别在两个容器中移动判断是否满足谓词条件(此处指是否相等),满足时返回第一个指向满足序列的首个元素的迭代器_First1
,否则返回_Last1
。
以下是运用该算法的简单示例:
string target="://";
string str="http://blog.csdn.net/github_35681219";
iter=search(str.begin(),str.end(),target.begin(),target.end());
if(iter==str.end())
cout<<"can't find it!"<<endl;
return iter;