C++STL 体系结构与内核分析(侯捷)——课程笔记(十二)

本部分内容包括STL中部分算法的介绍。

一般来说,算法是个函数模板,具有类似以下的格式:

template <typename Iterator>
std::Algorithm(Iterator itr1, Iterator itr2, ......)
{
    ......
}

1. accumulate()

accumulate()是累计函数,默认是加,也可以传入自定义操作

template <class InputIterator,
          class T>
T accumulate(InputIterator first,
             InputIterator last,
             T init)
{
    for( ; first != last; ++first)
        init = init + *first;
    return init;
}

template <class InputIterator,
          class T,
          class BinaryOperation>
T accumulate(InputIterator first,
             InputIterator last,
             T init,
             BinaryOperation binary_op)
{
    for( ; first != last; ++first)
        init = binary_op(init, *first);
    return init;
}

2. for_each()

对一个范围内的元素做某种操作

template <class InputIterator,
          class Function>
Function for_each(InputIterator first,
                  InputIterator last,
                  Function f)
{
    for( ; first != last; ++first)
        f(*first);
    return f;
}

该函数会返回一个值,但这个返回值会被忽略。还要注意不能通过迭代器修改元素的值,因为输入的是InputIterator,只读不能写

3. replace(), replace_if()和replace_copy()

template <class ForwardIterator, class T>
void replace(ForwardIterator first,
             ForwardIterator last,
             const T& old_value,
             const T& new_value){
    //范围内所有等同于old_value者都以new_value取代
    for(; first != last; ++first)
        if(*first == old_value)
            *first = new_value;
}

template <class ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first,
                ForwardIterator last,
                Predicate pred,
                const T& new_value){
    //范围内所有满足pred()为true者都以new_value取代
    for(; first != last; ++first)
        if(pred(*first))
            *first = new_value;
}

template <class ForwardIterator, class OutputIterator, class T>
OutputIterator replace_copy(ForwardIterator first,
                            ForwardIterator last,
                            OutputIterator result,
                            const T& old_value,
                            const T& new_value){
    //范围内所有等同于old_value者都以new_value放到新区间,不符合者原值放到新区间
    for(; first != last; ++first, ++result)
        *result = 
            *first == old_value ? new_value : *first;
    return result;
}

4. count()和count_if()

template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last,
      const T& value)
{
    typename iterator_traits<InputIterator>::difference_type n = 0;
    for(; first != last; ++first)
        if(*first == value)
            ++n;
    return n;
}

template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last,
         Predicate pred)
{
    typename iterator_traits<InputIterator>::difference_type n = 0;
    for(; first != last; ++first)
        if(pred(*first))
            ++n;
    return n;
}

5. find()和find_if()

template <class InputIterator, class T>
InputIterator find(InputIterator first,
                   InputIterator last,
                   const T& value)
{
    while(first != last && *first != value)
        ++first;
    return first;
}

template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first,
                      InputIterator last,
                      Predicate pred)
{
    while(first != last && !pred(*first))
        ++first;
    return first;
}

6. sort()

只介绍了sort()的用法。包含了一点rbegin()和rend()的内容,逆向迭代器的实现以后会讲。

7. binary_search()

用二分查找判断有序序列中是否存在某元素,内部工作是交给lower_bound()去做的。

template <class ForwardIterator, class T>
bool binary_search(ForwardIterator first,
                   ForwardIterator last,
                   const T& val)
{
    first = std::lower_bound(first, last, val);
    return (first != last && !(val < *first));
}

template <class ForwardIterator, class T>
ForwardIterator
lower_bound(ForwardIterator first,
            ForwardIterator last,
            const T& val)
{
    ForwardIterator it;
    iterator_traits<ForwardIterator>::difference_type count, step;
    count = distance(first, last);
    while(count > 0)
    {
        it = first; step = count / 2; advance(it, step);
        if(*it < val){
            first = ++it;
            count -= step + 1;
        }
        else count = step;
    }
    return first;
}

简单介绍一下lower_bound()和upper_bound():以从小到大排列的序列为例,lower_bound()返回的是第一个大于等于target的元素的位置,也就是第一个可以合法地插入target的位置;upper_bound()返回的是第一个大于target的元素,也就是最后一个可以合法地插入target的位置。当然都可能出现target不存在的情况,这时返回的要么是begin()要么是end(),然后再进行一下和头元素或尾元素的大小判断就能知道target是否存在了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值