STL之---search算法源码分析

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;
点赞