STL algorithm(转)

本文详细介绍了C++标准模板库(STL)中的各种算法,包括基础算法、复制算法、比较算法、填充算法、线性查找算法等,并提供了部分算法的具体实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STL algorithm(转)

snowman 发表于 2007-03-08 16:33:37

/*
The young Library
Copyright (c) 2005 by 杨桓

Permission to use, copy, modify, distribute and sell this software for any
purpose is hereby granted without fee, provided that the above copyright
notice appear in all copies and that both that copyright notice and this
permission notice appear in supporting documentation.
The author make no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
*/

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

/*
基础算法: min, max, swap, *gcd, *median

复制算法: copy  *copy_n  copy_backward  *copy_backward_n  *copy_if  *copy_range

比较算法: equal  lexicographical_compare  mismatch  *matching

填充算法: fill, fill_n

线性查找算法: find, find_if, adiancent_find, find_first_of,
              *find_all, *find_all_if

子序列匹配算法: search, find_end, search_n

计算元素个数算法: count, count_if

最大值与最小值算法: min_element, max_element

互换算法: iter_swap, swap_ranges

遍历区间算法: for_earch, generate, generate_n, transform

替换元素算法: replace, replace_if, replace_copy, replace_copy_if

移除元素算法: remove, remove_if, remove_copy, remove_copy_if,
              unique, unique_copy

排列算法: reverse, reverse_copy, rotate, rotate_copy,
          prev_permutation, next_permutation

分割算法: partition, stable_partition

随机重排与抽样算法: random_shuffle, *random_sample, *random_sample_n

二分查找算法: lower_bound, upper_bound, equal_range, binary_search

区间合并算法: merge, *merge_backward, inplace_merge

区间集合算法: includes, set_union, set_intersection, set_difference,
              set_symmetric_difference

排序算法: *is_sorted, sort, stable_sort, partial_sort, partial_sort_copy,
          nth_element

堆算法: push_heap, pop_heap, make_heap, sort_heap, *is_heap
*/

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifndef __MACRO_CPLUSPLUS_YOUNG_LIBRARY_ALGORITHM_HEADER_FILE__
#define __MACRO_CPLUSPLUS_YOUNG_LIBRARY_ALGORITHM_HEADER_FILE__
//-----------------------------------------------------------------------------
#include <cstdlib>  //rand()函数
#include "y_temp_buffer.hpp"
#include "algorithm/y_algorithm_base.hpp"
#include "algorithm/y_algorithm_compare.hpp"
#include "algorithm/y_algorithm_copy.hpp"
#include "algorithm/y_algorithm_fill.hpp"
#include "algorithm/y_algorithm_heap.hpp"
#include "algorithm/y_algorithm_lower_bound.hpp"
//-----------------------------------------------------------------------------
__MACRO_CPLUSPLUS_YOUNG_LIBRARY_BEGIN_NAMESPACE__
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename T >
T gcd( T m, T n )  //求最大公因数
{
    while( n != 0 )
    {
        T x = m % n;
        m = n;
        n = x;
    }
    return m;
}

template< typename T >
const T& median( const T& a, const T& b, const T& c )  //求中间值
{
    if( a < b )
    {
        if( b < c )  //a < b < c
            return b;
        else if( a < c )  //a < b && c <= b
            return c;
        else
            return a;
    }
    else if( a < c )  //a >= b
        return a;
    else if( b < c )  //a >=b && a >=c
        return c;
    else
        return b;
}

template< typename T, typename StrictWeakOrdering >
const T& median( const T& a, const T& b, const T& c,
                        StrictWeakOrdering comp )
{
    if( comp(a, b) )
    {
        if( comp(b, c) )
            return b;
        else if( comp(a, c) )
            return c;
        else
            return a;
    }
    else if( comp(a, c) )
        return a;
    else if( comp(b, c) )
        return c;
    else
        return b;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                            线性查找算法
//
//     find  find_if  adiancent_find  find_first_of  find_all  find_all_if
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename InputIterator, typename T >
inline InputIterator find( InputIterator first, InputIterator last,
                           const T& value )
{
    typedef  typename iterator_traits<InputIterator>::iterator_category  cate;
    return  find_aux( first, last, value, cate() );
}

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

template< typename InputIterator, typename T >
InputIterator find_aux( InputIterator first, InputIterator last,
                        const T& value, random_access_iterator_tag )
{
    typedef  typename iterator_traits<InputIterator>::difference_type  diff_t;

    diff_t n = last - first;
    while( n > 0 && *first != value )
    {
        --n;
        ++first;
    }
    return first;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename UnaryPredicate >
inline InputIterator find_if( InputIterator first, InputIterator last,
                              UnaryPredicate pred )
{
    typedef  typename iterator_traits<InputIterator>::iterator_category  cate;
    return  find_aux( first, last, pred, cate() );
}

template< typename InputIterator, typename UnaryPredicate >
InputIterator find_if_aux( InputIterator first, InputIterator last,
                           UnaryPredicate pred, input_iterator_tag )
{
    while( first != last && !pred(*first) )
        ++first;
    return first;
}

template< typename InputIterator, typename UnaryPredicate >
InputIterator find_if_aux( InputIterator first, InputIterator last,
                           UnaryPredicate pred, random_access_iterator_tag )
{
    typedef  typename iterator_traits<InputIterator>::difference_type  diff_t;

    diff_t n = last - first;
    while( n > 0 && !pred(*first) )
    {
        --n;
        ++first;
    }
    return first;
}

//-----------------------------------------------------------------------------

//寻找[first, last)中第一次出现相邻值相等的位置
template< typename ForwardIterator >
inline
ForwardIterator adjacent_find( ForwardIterator first, ForwardIterator last )
{
    typedef  typename iterator_traits<ForwardIterator>::iterator_category  cate;

    if( first == last )
        return last;
    else
        return ad_find_aux( first, last, cate() );
}

template< typename ForwardIterator >
ForwardIterator ad_find_aux( ForwardIterator first, ForwardIterator last,
                             forward_iterator_tag )
{
    ForwardIterator next = first;
    ++next;
    for( ; next != last; ++next )
    {
        if( *first == *next )
            return first;
        else
            first = next;
    }
    return last;
}

template< typename ForwardIterator >
ForwardIterator ad_find_aux( ForwardIterator first, ForwardIterator last,
                             random_access_iterator_tag )
{
    typedef  typename iterator_traits<ForwardIterator>::difference_type  diff_t;

    ForwardIterator next = first;
    ++next;
    for( diff_t n = last - first; n > 0; --n,++next )
    {
        if( *first == *next )
            return first;
        else
            first = next;
    }
    return last;
}

template< typename ForwardIterator, typename BinaryPredicate >
inline
ForwardIterator adjacent_find( ForwardIterator first, ForwardIterator last,
                               BinaryPredicate bin_pred )
{
    typedef  typename iterator_traits<ForwardIterator>::iterator_category  cate;

    if( first == last )
        return last;
    else
        return ad_find_aux( first, last, bin_pred, cate() );
}

template< typename ForwardIterator, typename BinaryPredicate >
ForwardIterator ad_find_aux( ForwardIterator first, ForwardIterator last,
                             BinaryPredicate bin_pred,
                             forward_iterator_tag )
{
    ForwardIterator next = first;
    ++next;
    for( ; next != last; ++next )
    {
        if( bin_pred(*first, *next) )
            return first;
        else
            first = next;
    }
    return last;
}

template< typename ForwardIterator, typename BinaryPredicate >
ForwardIterator ad_find_aux( ForwardIterator first, ForwardIterator last,
                             BinaryPredicate bin_pred,
                             random_access_iterator_tag )
{
    typedef  typename iterator_traits<ForwardIterator>::difference_type  diff_t;

    ForwardIterator next = first;
    ++next;
    for( diff_t n = last - first; n > 0; --n,++next )
    {
        if( bin_pred(*first, *next) )
            return first;
        else
            first = next;
    }
    return last;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename ForwardIterator >
InputIterator find_first_of( InputIterator first1, InputIterator last1,
                             ForwardIterator first2, ForwardIterator last2 )
{
    for( ; first1 != last1; ++first1 )
    {
        for( ForwardIterator temp = first2; temp != last2; ++temp )
        {
            if( *first1 == *temp )
                return first1;
        }
    }
    return last1;
}

template< typename InputIterator, typename ForwardIterator,
          typename BinaryPredicate >
InputIterator find_first_of( InputIterator first1, InputIterator last1,
                             ForwardIterator first2, ForwardIterator last2,
                             BinaryPredicate bin_pred )
{
    for( ; first1 != last1; ++first1 )
    {
        for( ForwardIterator temp = first2; temp != last2; ++temp )
        {
            if( bin_pred(*first1, *temp) )
                return first1;
        }
    }
    return last1;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename T, typename OutputIterator >
OutputIterator find_all( InputIterator first,
                         InputIterator last,
                         OutputIterator result_first,
                         OutputIterator result_last,
                         const T& value )
{
    for( ; first != last && result_first != result_last; ++first )
    {
     if( *first == value )
     {
         *result_first = first;
         ++result_first;
     }
    }

    return result_first;
}

template< typename InputIterator, typename Container, typename T >
void find_all( InputIterator first, InputIterator last, Container& result,
               const T& value )
{
    typename Container::iterator  itr1 = result.begin();
    typename Container::iterator  itr2 = result.end();

    for( ; first != last; ++first )
    {
     if( *first == value )
     {
         if( itr1 != itr2 )
         {
             *itr1 = first;
             ++itr1;
         }
         else
             result.push_back( first );
     }
    }
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator,
          typename UnaryPredicate >
OutputIterator find_all_if( InputIterator first,
                            InputIterator last,
                            OutputIterator result_first,
                            OutputIterator result_last,
                            UnaryPredicate pred )
{
    for( ; first != last && result_first != result_last; ++first )
    {
     if( pred(*first) )
     {
         *result_first = first;
         ++result_first;
     }
    }

    return result_first;
}

template< typename InputIterator, typename Container, typename UnaryPredicate >
void find_all_if( InputIterator first, InputIterator last, Container& result,
                  UnaryPredicate pred )
{
    typename Container::iterator itr1 = result.begin();
    typename Container::iterator itr2 = result.end();

    for( ; first != last; ++first )
    {
     if( pred(*first) )
     {
         if( itr1 != itr2 )
         {
             *itr1 = first;
             ++itr1;
         }
         else
             result.push_back( first );
     }
    }
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                             子序列匹配算法
//
//                        search  find_end  search_n
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//[first2, last2)是否包含于[first1, last1)
template< typename ForwardIterator1, typename ForwardIterator2 >
ForwardIterator1 search( ForwardIterator1 first1, ForwardIterator1 last1,
                         ForwardIterator2 first2, ForwardIterator2 last2 )
{
    typedef  typename iterator_traits<ForwardIterator1>::difference_type
             diff_t1;
    typedef  typename iterator_traits<ForwardIterator2>::difference_type
             diff_t2;

    diff_t1 len1 = distance( first1, last1 );
    diff_t2 len2 = distance( first2, last2 );

    if( len1 < len2 )
        return last1;

    ForwardIterator1 current1 = first1;
    ForwardIterator2 current2 = first2;

    while( current2 != last2 )
    {
        if( *current1 == *current2 )
        {
            ++current1;
            ++current2;
        }
        else  //遇到不相等时的处理
        {
            if( len1 == len2 )  //此时first1再前进则len1<len2,匹配失败
                return last1;
            else
            {
                current1 = ++first1;  //first1前进一个位置,重新开始匹配
                current2 = first2;
                --len1;
            }
        }
    }

    return first1;
}

template< typename ForwardIterator1, typename ForwardIterator2,
          typename BinaryPredicate >
ForwardIterator1 search( ForwardIterator1 first1, ForwardIterator1 last1,
                         ForwardIterator2 first2, ForwardIterator2 last2,
                         BinaryPredicate bin_pred )
{
    typedef  typename iterator_traits<ForwardIterator1>::difference_type
             diff_t1;
    typedef  typename iterator_traits<ForwardIterator2>::difference_type
             diff_t2;

    diff_t1 len1 = distance( first1, last1 );
    diff_t2 len2 = distance( first2, last2 );

    if( len1 < len2 )
        return last1;

    ForwardIterator1 current1 = first1;
    ForwardIterator2 current2 = first2;

    while( current2 != last2 )
    {
        if( bin_pred(*current1, *current2) )
        {
            ++current1;
            ++current2;
        }
        else
        {
            if( len1 == len2 )
                return last1;
            else
            {
                current1 = ++first1;
                current2 = first2;
                --len1;
            }
        }
    }

    return first1;
}

//-----------------------------------------------------------------------------

//在 [first1, last1) 中查找 [first2, last2)
template< typename ForwardIterator1, typename ForwardIterator2 >
inline ForwardIterator1
find_end( ForwardIterator1 first1, ForwardIterator1 last1,
          ForwardIterator2 first2, ForwardIterator2 last2 )
{
    typedef  typename iterator_traits<ForwardIterator1>::iterator_category
             cate1;
    typedef  typename iterator_traits<ForwardIterator2>::iterator_category
             cate2;

    if( first1 == last1 || first2 == last2 )
        return last1;
    else
        return find_end_aux( first1, last1, first2, last2, cate1(), cate2() );
}

template< typename ForwardIterator1, typename ForwardIterator2 >
ForwardIterator1
find_end_aux( ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              forward_iterator_tag, forward_iterator_tag )
{
    ForwardIterator1 result = last1;

    while( 1 )
    {
        ForwardIterator1 new_result = search( first1, last1, first2, last2 );
        if( new_result == last1 )
            return result;
        else
        {
            result = new_result;
            first1 = new_result;
            ++first1;
        }
    }  //end while
}

template< typename ForwardIterator1, typename ForwardIterator2 >
ForwardIterator1
find_end_aux( ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              bidirectional_iterator_tag, bidirectional_iterator_tag )
{
    typedef  Reverse_Iterator<ForwardIterator1>  r_iter1;
    typedef  Reverse_Iterator<ForwardIterator2>  r_iter2;

    r_iter1 rlast1( first1 );
    r_iter2 rlast2( first2 );

    //反向匹配的第一个即为正向的最后一个
    r_iter1 rresult = search( r_iter1(last1), rlast1, r_iter2(last2), rlast2 );

    if( rresult = rlast1 )
        return last1;
    else
    {
        ForwardIterator1 result = rresult.base();
        advance( result, -distance(first2, last2) );  //前进到匹配子序列的开头
        return result;
    }
}

template< typename ForwardIterator1, typename ForwardIterator2,
          typename BinaryPredicate >
inline ForwardIterator1
find_end( ForwardIterator1 first1, ForwardIterator1 last1,
          ForwardIterator2 first2, ForwardIterator2 last2,
          BinaryPredicate bin_pred )
{
    typedef  typename iterator_traits<ForwardIterator1>::iterator_category
             cate1;
    typedef  typename iterator_traits<ForwardIterator2>::iterator_category
             cate2;

    if( first1 == last1 || first2 == last2 )
        return last1;
    else
        return find_end_aux( first1, last1, first2, last2, bin_pred,
                             cate1(), cate2() );
}

template< typename ForwardIterator1, typename ForwardIterator2,
          typename BinaryPredicate >
ForwardIterator1
find_end_aux( ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              BinaryPredicate bin_pred,
              forward_iterator_tag, forward_iterator_tag )
{
    ForwardIterator1 result = last1;

    while( 1 )
    {
        ForwardIterator1 new_result = search( first1, last1, first2, last2,
                                              bin_pred );
        if( new_result == last1 )
            return result;
        else
        {
            result = new_result;
            first1 = new_result;
            ++first1;
        }
    }
}

template< typename ForwardIterator1, typename ForwardIterator2,
          typename BinaryPredicate >
ForwardIterator1
find_end_aux( ForwardIterator1 first1, ForwardIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              BinaryPredicate bin_pred,
              bidirectional_iterator_tag, bidirectional_iterator_tag )
{
    typedef  Reverse_Iterator<ForwardIterator1>  r_iter1;
    typedef  Reverse_Iterator<ForwardIterator2>  r_iter2;

    r_iter1 rlast1( first1 );
    r_iter2 rlast2( first2 );

    r_iter1 rresult = search( r_iter1(last1), rlast1, r_iter2(last2), rlast2,
                              bin_pred );

    if( rresult = rlast1 )
        return last1;
    else
    {
        ForwardIterator1 result = rresult.base();
        advance( result, -distance(first2, last2) );
        return result;
    }
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator, typename Integer, typename T >
ForwardIterator search_n( ForwardIterator first, ForwardIterator last,
                          Integer count, const T& value )
{
    if( count < 1 )
        return first;

    first = find( first, last, value );  //找到第一个要查找的值

    while( first != last )
    {
        Integer n = count - 1;
        ForwardIterator itr = first;
        ++itr;

        while( itr != last && n != 0 && *i == value )  //向后进行迭代并比较
        {
            ++itr;
            --n;
        }

        if( n == 0 )
            return first;
        else
            first = find( itr, last, value );
    }

    return last;
}

template< typename ForwardIterator, typename Integer, typename T,
          typename BinaryPredicate >
ForwardIterator search_n( ForwardIterator first, ForwardIterator last,
                          Integer count, const T& value,
                          BinaryPredicate bin_pred )
{
    if( count < 1 )
        return first;

    while( first != last )
    {
        if( binary_pred(*first, value) )
            break;
        ++first;
    }

    while( first != last )
    {
        Integer n = count - 1;
        ForwardIterator itr = first;
        ++itr;

        while( itr != last && n != 0 && bin_pred(*i, value) )
        {
            ++itr;
            --n;
        }

        if( n == 0 )
            return first;
        else
        {
            while( itr != last )
            {
                if( binary_pred(*itr, value) )
                    break;
                ++itr;
            }
            first = itr;
        }
    }

    return last;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                             计算元素个数算法
//
//                             count  count_if
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename InputIterator, typename T >
inline typename iterator_traits<InputIterator>::difference_type
count( InputIterator first, InputIterator last, const T& value )
{
    typedef  typename iterator_traits<InputIterator>::iterator_category  cate;
    return count_aux( first, last, value, cate() );
}

template< typename InputIterator, typename T >
typename iterator_traits<InputIterator>::difference_type
count_aux( InputIterator first, InputIterator last, const T& value,
           input_iterator_tag )
{
    typename iterator_traits<InputIterator>::difference_type  count = 0;

    for( ; first != last; ++first )
    {
        if( *first == value )
            ++count;
    }
    return count;
}

template< typename InputIterator, typename T >
typename iterator_traits<InputIterator>::difference_type
count_aux( InputIterator first, InputIterator last, const T& value,
           random_access_iterator_tag )
{
    typename iterator_traits<InputIterator>::difference_type  count = 0;
    typename iterator_traits<InputIterator>::difference_type  n = last - first;

    for( ; n > 0; --n,++first )
    {
        if( *first == value )
            ++count;
    }
    return count;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename UnaryPredicate >
inline typename iterator_traits<InputIterator>::difference_type
count_if( InputIterator first, InputIterator last, UnaryPredicate pred )
{
    typedef  typename iterator_traits<InputIterator>::iterator_category  cate;
    return count_if_aux( first, last, pred, cate() );
}

template< typename InputIterator, typename UnaryPredicate >
typename iterator_traits<InputIterator>::difference_type
count_if_aux( InputIterator first, InputIterator last, UnaryPredicate pred,
              input_iterator_tag )
{
    typename iterator_traits<InputIterator>::difference_type  count = 0;

    for( ; first != last; ++first )
    {
        if( pred(*first) )
            ++count;
    }
    return count;
}

template< typename InputIterator, typename UnaryPredicate >
typename iterator_traits<InputIterator>::difference_type
count_if_aux( InputIterator first, InputIterator last, UnaryPredicate pred,
              random_access_iterator_tag )
{
    typename iterator_traits<InputIterator>::difference_type  count = 0;
    typename iterator_traits<InputIterator>::difference_type  n = last - first;

    for( ; n > 0; --n,++first )
    {
        if( pred(*first) )
            ++count;
    }
    return count;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                             最大值与最小值算法
//
//                          min_element  max_element
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename ForwardIterator >
ForwardIterator min_element( ForwardIterator first, ForwardIterator last )
{
    if( first == last )
        return first;

    ForwardIterator result = first;
    for( ; first != last; ++first )
    {
        if( *first < *result )
            result = first;
    }
    return result;
}

template< typename ForwardIterator, typename StrictWeakOrdering >
ForwardIterator min_element( ForwardIterator first, ForwardIterator last,
                             StrictWeakOrdering comp )
{
    if( first == last )
        return first;

    ForwardIterator result = first;
    for( ; first != last; ++first )
    {
        if( comp(*first, *result) )
            result = first;
    }
    return result;
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator >
ForwardIterator max_element( ForwardIterator first, ForwardIterator last )
{
    if( first == last )
        return first;

    ForwardIterator result = first;
    for( ; first != last; ++first )
    {
        if( *result < *first )
            result = first;
    }
    return result;
}

template< typename ForwardIterator, typename StrictWeakOrdering >
ForwardIterator max_element( ForwardIterator first, ForwardIterator last,
                             StrictWeakOrdering comp )
{
    if( first == last )
        return first;

    ForwardIterator result = first;
    for( ; first != last; ++first )
    {
        if( comp(*result, *first) )
            result = first;
    }
    return result;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                                互换算法
//
//                          iter_swap  swap_ranges
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename ForwardIterator1, typename ForwardIterator2 >
inline void iter_swap( ForwardIterator1 lhs, ForwardIterator2 rhs )
{
    typename iterator_traits<ForwardIterator1>::value_type  temp = *lhs;
    *lhs = *rhs;
    *rhs = temp;
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator1, typename ForwardIterator2 >
inline
ForwardIterator2 swap_ranges( ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2 )
{
    typedef  typename iterator_traits<ForwardIterator1>::iterator_category  cate;
    return swap_r_aux( first1, last1, first2, cate() );
}

template< typename ForwardIterator1, typename ForwardIterator2 >
ForwardIterator2 swap_r_aux( ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2,
                             forward_iterator_tag )
{
    for( ; first1 != last1; ++first1,++first2 )
        iter_swap( first1, first2 );
    return first2;
}

template< typename ForwardIterator1, typename ForwardIterator2 >
ForwardIterator2 swap_r_aux( ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2,
                             random_access_iterator_tag )
{
    typedef  typename iterator_traits<ForwardIterator1>::difference_type
             diff_t1;

    for( diff_t1 n = last1 - first1; n > 0; --n,++first1,++first2 )
        iter_swap( first1, first2 );
    return first2;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                       使用Function Object遍历区间的算法
//
//                   for_earch  generate  generate_n  transform
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

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

//-----------------------------------------------------------------------------

template< typename ForwardIterator, typename Generator >
void generate( ForwardIterator first, ForwardIterator last, Generator gen )
{
    for( ; first != last; ++first )
        *first = gen();
}

//-----------------------------------------------------------------------------

template< typename OutputIterator, typename Integer, typename Generator >
OutputIterator generate_n( OutputIterator first, Integer n, Generator gen )
{
    typedef  typename primal_type<Integer>::primal_t  primal_int;

    for( primal_int i = 0; i < n; ++i, ++first )
        *first = gen();
    return first;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator,
          typename UnaryOperation >
OutputIterator transform( InputIterator first, InputIterator last,
                          OutputIterator result, UnaryOperation op )
{
    for( ; first != last; ++first,++result )
        *result = op( *first );
    return result;
}

template< typename InputIterator1, typename InputIterator2,
          typename OutputIterator, typename BinaryOperation >
OutputIterator transform( InputIterator1 first1, InputIterator1 last1,
                          InputIterator2 first2, OutputIterator result,
                          BinaryOperation bin_op )
{
    for( ; first1 != last1; ++first1,++first2,++result )
        *result = bin_op( *first1, *first2 );
    return result;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                               替换元素算法
//
//             replace  replace_if  replace_copy  replace_copy_if
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename ForwardIterator, typename T >
inline void replace( ForwardIterator first, ForwardIterator last,
                     const T& old_value, const T& new_value )
{
    typedef  typename iterator_traits<ForwardIterator>::iterator_category  cate;
    replace_aux( first, last, old_value, new_value, cate() );
}

template< typename ForwardIterator, typename T >
void replace_aux( ForwardIterator first, ForwardIterator last,
                  const T& old_value, const T& new_value,
                  forward_iterator_tag )
{
    for( ; first != last; ++first )
    {
        if( *first == old_value )
            *first = new_value;
    }
}

template< typename ForwardIterator, typename T >
void replace_aux( ForwardIterator first, ForwardIterator last,
                  const T& old_value, const T& new_value,
                  random_access_iterator_tag )
{
    typedef  typename iterator_traits<ForwardIterator>::difference_type  diff_t;

    for( diff_t n = last - first; n > 0; --n,++first )
    {
        if( *first == old_value )
            *first = new_value;
    }
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator, typename UnaryPredicate, typename T >
inline void replace_if( ForwardIterator first, ForwardIterator last,
                        UnaryPredicate pred, const T& new_value )
{
    typedef  typename iterator_traits<ForwardIterator>::iterator_category  cate;
    replace_if_aux( first, last, pred, new_value, cate() );
}

template< typename ForwardIterator, typename UnaryPredicate, typename T >
void replace_if_aux( ForwardIterator first, ForwardIterator last,
                     UnaryPredicate pred, const T& new_value,
                     forward_iterator_tag )
{
    for( ; first != last; ++first )
    {
        if( pred(*first) )
            *first = new_value;
    }
}

template< typename ForwardIterator, typename UnaryPredicate, typename T >
void replace_if_aux( ForwardIterator first, ForwardIterator last,
                     UnaryPredicate pred, const T& new_value,
                     random_access_iterator_tag )
{
    typedef  typename iterator_traits<ForwardIterator>::difference_type  diff_t;

    for( diff_t n = last - first; n > 0; --n,++first )
    {
        if( pred(*first) )
            *first = new_value;
    }
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator, typename T >
inline OutputIterator replace_copy( InputIterator first, InputIterator last,
                                    OutputIterator result,
                                    const T& old_value, const T& new_value )
{
    typedef  typename iterator_traits<InputIterator>::iterator_category  cate;
    return  replace_cp_aux( first, last, result, old_value, new_value, cate() );
}

template< typename InputIterator, typename OutputIterator, typename T >
OutputIterator replace_cp_aux( InputIterator first, InputIterator last,
                               OutputIterator result,
                               const T& old_value, const T& new_value,
                               input_iterator_tag )
{
    for( ; first != last; ++first,++result )
    {
        if( *first == old_value )
            *result = new_value;
        else
            *result = *first;
    }
    return result;
}

template< typename InputIterator, typename OutputIterator, typename T >
OutputIterator replace_cp_aux( InputIterator first, InputIterator last,
                               OutputIterator result,
                               const T& old_value, const T& new_value,
                               random_access_iterator_tag )
{
    typedef  typename iterator_traits<InputIterator>::difference_type  diff_t;

    for( diff_t n = last - first; n > 0; --n,++first,++result )
    {
        if( *first == old_value )
            *result = new_value;
        else
            *result = *first;
    }
    return result;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator,
          typename UnaryPredicate, typename T >
inline
OutputIterator replace_copy_if( InputIterator first, InputIterator last,
                                OutputIterator result,
                                UnaryPredicate pred, const T& new_value )
{
    typedef  typename iterator_traits<InputIterator>::iterator_category  cate;
    return  replace_cp_if_aux( first, last, result, pred, new_value, cate() );
}

template< typename InputIterator, typename OutputIterator,
          typename UnaryPredicate, typename T >
OutputIterator replace_cp_if_aux( InputIterator first, InputIterator last,
                                  OutputIterator result,
                                  UnaryPredicate pred, const T& new_value,
                                  input_iterator_tag )
{
    for( ; first != last; ++first,++result )
    {
        if( pred(*first) )
            *result = new_value;
        else
            *result = *first;
    }
    return result;
}

template< typename InputIterator, typename OutputIterator,
          typename UnaryPredicate, typename T >
OutputIterator replace_cp_if_aux( InputIterator first, InputIterator last,
                                  OutputIterator result,
                                  UnaryPredicate pred, const T& new_value,
                                  random_access_iterator_tag )
{
    typedef  typename iterator_traits<InputIterator>::difference_type  diff_t;

    for( diff_t n = last - first; n > 0; --n,++first,++result )
    {
        if( pred(*first) )
            *result = new_value;
        else
            *result = *first;
    }
    return result;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                               移除元素算法
//
//     remove  remove_if  remove_copy  remove_copy_if  unique  unique_copy
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator, typename T >
OutputIterator remove_copy( InputIterator first, InputIterator last,
                            OutputIterator result, const T& value )
{
    for( ; first != last; ++first )
    {
        if( *first != value )
        {
            *result = *first;
            ++result;
        }
    }
    return result;
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator, typename Predicate >
OutputIterator remove_copy_if( InputIterator first, InputIterator last,
                               OutputIterator result, Predicate pred )
{
    for( ; first != last; ++first )
    {
        if( !pred(*first) )
        {
            *result = *first;
            ++result;
        }
    }
    return result;
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator, typename T >
ForwardIterator remove( ForwardIterator first, ForwardIterator last,
                        const T& value )
{
    while( first != last && *first != value )  //找到第一个出现value的位置
        ++first;

    ForwardIterator next = first;
    if( first == last )
        return last;
    else
        return remove_copy( ++next, last, first, value );
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator, typename Predicate >
ForwardIterator remove_if( ForwardIterator first, ForwardIterator last,
                           Predicate pred )
{
    while( first != last && !pred(*first) )
        ++first;

    ForwardIterator next = first;
    if( first == last )
        return last;
    else
        return remove_copy( ++next, last, first, value );
}

//-----------------------------------------------------------------------------

template< typename InputIterator, typename OutputIterator >
inline OutputIterator unique_copy( InputIterator first, InputIterator last,
                                   OutputIterator result )
{
    typedef  typename iterator_traits<OutputIterator>::iterator_category  cate;

    if( first == last )
        return result;

    return unique_copy_aux( first, last, result, cate() );
}

template< typename InputIterator, typename OutputIterator >
OutputIterator unique_copy_aux( InputIterator first, InputIterator last,
                                OutputIterator result, output_iterator_tag )
{
    typedef  typename iterator_traits<OutputIterator>::value_type  value_t;

    value_t value = *first;
    *result = value;
    ++first;

    for( ; first != last; ++first )
    {
        if( value != *first )
        {
            value = *first;
            *(++result) = value;
        }
    }

    return ++result;
}

template< typename InputIterator, typename OutputIterator >
OutputIterator unique_copy_aux( InputIterator first, InputIterator last,
                                OutputIterator result, forward_iterator_tag )
{
    *result = *first;
    ++first;

    for( ; first != last; ++first )
    {
        if( *result != *first )
            *(++result) = *first;
    }

    return ++result;
}

template< typename InputIterator, typename OutputIterator,
          typename BinaryPredicate >
inline OutputIterator unique_copy( InputIterator first, InputIterator last,
                                   OutputIterator result,
                                   BinaryPredicate bin_pred )
{
    typedef  typename iterator_traits<OutputIterator>::iterator_category  cate;

    if( first == last )
        return result;

    return unique_copy_aux( first, last, result, bin_pred, cate() );
}

template< typename InputIterator, typename OutputIterator,
          typename BinaryPredicate >
OutputIterator unique_copy_aux( InputIterator first, InputIterator last,
                                OutputIterator result,
                                BinaryPredicate bin_pred,
                                output_iterator_tag )
{
    typedef  typename iterator_traits<OutputIterator>::value_type  value_t;

    value_t value = *first;
    *result = value;
    ++first;

    for( ; first != last; ++first )
    {
        if( bin_pred(value, *first) )
        {
            value = *first;
            *(++result) = value;
        }
    }

    return ++result;
}

template< typename InputIterator, typename OutputIterator,
          typename BinaryPredicate >
OutputIterator unique_copy_aux( InputIterator first, InputIterator last,
                                OutputIterator result,
                                BinaryPredicate bin_pred,
                                forward_iterator_tag )
{
    *result = *first;
    ++first;

    for( ; first != last; ++first )
    {
        if( bin_pred(*result, *first) )
            *(++result) = *first;
    }

    return ++result;
}

//-----------------------------------------------------------------------------

template< typename ForwardIterator >
ForwardIterator unique( ForwardIterator first, ForwardIterator last )
{
    ForwardIterator next = first;
    ++next;
    for( ; next != last; ++next )
    {
        if( *first == *next )
            return first;
        else
            first = next;
    }

    if( first == last )
        return last;
    else
        return unique_copy( first, last, first );
}

template< typename ForwardIterator, typename BinaryPredicate >
ForwardIterator unique( ForwardIterator first, ForwardIterator last,
                        BinaryPredicate bin_pred )
{
    ForwardIterator next = first;
    ++next;
    for( ; next != last; ++next )
    {
        if( bin_pred(*first, *next) )
            return first;
        else
            first = next;
    }

    if( first == last )
        return last;
    else
        return unique_copy( first, last, first, bin_pred );
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//*****************************************************************************
//*****************************************************************************
//                               排列算法
//
//              reverse  reverse_copy  rotate  rotate_copy
//                  prev_permutation  next_permutation
//*****************************************************************************
//*****************************************************************************

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

template< typename BidirectionalIterator >
inline void reverse( BidirectionalIterator first, BidirectionalIterator last )
{
    typedef  typename iterator_traits<BidirectionalIterator>::iterator_category
             cate;

    reverse_aux( first, last, cate() );
}

template< typename BidirectionalIterator >
void reverse_aux( BidirectionalIterator first, BidirectionalIterator last,
                  bidirectional_iterator_tag )
{
    typedef  typename iterator_traits<BidirectionalIterator>::value_type
             value_t;

    while( 1 )
    {
        if( first == last || first == --last )
            return;
        val

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值