STL

基础算法: 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 >
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、付费专栏及课程。

余额充值