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