STL 算法库函数模拟 ( unique | merge_sort | random_shuffle | ......)

 *自定义函数
*transform
*merge_sort
*remove_if
*erase_if
*range_set
*copy
*inplace_merge
*unique
*random_shuffle
*find_if

 

template< std::size_t _ArrayLength, typename _Ty >
std::ostream& operator<<( std::ostream& out, _Ty ( &array )[ _ArrayLength ] ){
	std::copy( std::begin( array ),
			   std::end( array ),
			   std::ostream_iterator< _Ty >( out, "|") );
	return out;
}
static int increment { 0 };
int main( void ){
	int array[ 12 ] { 0, };
	::std::transform( ::std::cbegin( array ),
					::std::cend( array ),
					::std::begin( array ),
					[&]( int e ){
		return (increment++) % 4 + 1;
	});
	puts("initialized...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	random_shuffle( ::std::begin( array ), ::std::end( array ) );
	puts("\n\nrandom shuffled...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	merge_sort( std::begin( array ), ::std::end( array ) ,
	[&]( const int& v1, const int& v2 )->bool{ return v1 < v2; } );
	puts("\n\nsorted...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	int p = unique( array, [&]( const int& v1, const int& v2 )
	->bool{ return v1 == v2; } ) - ( int *)array;
	puts("\n\nunique processed..");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	erase_if( array + p, 12 - p, [&]( int& ){ return true; }, -1 );
	puts("\n\ntrail pait erased...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );
	return 0;
}

 

#include <utility>
#include <iostream>
#include <type_traits>
#include <algorithm>
#include <iterator>
#include <memory>


#ifdef INPLACE_MERGE
template <typename InputIt, typename OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first ){
	for( ; !( first == last ); ( void )++first, ( void )++d_first )
		*d_first = *first;
	return d_first;
}

template < typename BidirectionalIt , typename BinaryPredicate >
void inplace_merge( BidirectionalIt first,
					BidirectionalIt middle,
					BidirectionalIt last,
					BinaryPredicate comp ){
	BidirectionalIt __end_left   = middle++;
	BidirectionalIt __end_right  =     last;
	BidirectionalIt __beg_origin =    first;
	typedef typename
	::std::iterator_traits< BidirectionalIt >::value_type
	_ValueType;
	typedef typename
	::std::iterator_traits< BidirectionalIt >::difference_type
	_DistanceType;
	if( first == middle || middle == last ) return;
	using __Const_DistanceType
		= ::std::add_const< _DistanceType >::type;
	__Const_DistanceType __len_right =
		::std::distance( first, middle );
	__Const_DistanceType __len_left =
		::std::distance( middle, last );
	_ValueType *__tempBuf = new _ValueType[ __len_left + __len_right + 1 ];
	::std::shared_ptr< _ValueType > __deleteGuarder(__tempBuf);
	::std::ptrdiff_t __ptr { 0 };
	while( !(first  == __end_left)
	||     !(middle == __end_right) )
		*( __tempBuf + ( __ptr++ ) ) =
			( middle >= __end_right )
		 || (  first < __end_left
		 &&    comp( *first, *middle ) )?
		 *first++ : *middle++;
	copy( __tempBuf, __tempBuf + (__len_left + __end_right), __beg_origin);
}
#endif

template < std::size_t _ArrayLength, typename _Ty, typename _UnaryPredicate >
std::size_t find_if( _Ty ( &array )[ _ArrayLength ], _UnaryPredicate p ){
	std::size_t first { 0 };
	for( ; !( first == _ArrayLength )
	    && !p( *( ( _Ty *)array + first ) )
		; ++first ) {                     }
	return first;
}
template < typename _Ty, typename _UnaryPredicate >
std::size_t find_if( _Ty *pArray, std::size_t _tN ,_UnaryPredicate p ){
	std::size_t first { 0 };
	for( ; !( first == _tN )
	    && !p( *( pArray + first ) )
		; ++first ) {                     }
	return first;
}

template < std::size_t _ArrayLength, typename _Ty, typename _UnaryPredicate >
std::size_t remove_if( _Ty ( &array )[ _ArrayLength ], _UnaryPredicate p ){
	std::size_t first = find_if( array, p),
				last   = _ArrayLength;
	if( first == last ) return last;
	for( std::size_t iter { first }; !( ++iter == last ); ){
		_Ty& __ref_ = *( ( _Ty *)array + iter );
		if( !p( __ref_ ) )
			array[ first++ ] = std::move( __ref_ );
	}
	return first;
}
template < typename _Ty, typename _UnaryPredicate >
std::size_t remove_if( _Ty *pArray, std::size_t _tN, _UnaryPredicate p ){
	std::size_t first = find_if( pArray, _tN, p),
				last   = _tN;
	if( first == last ) return last;
	for( std::size_t iter { first }; !( ++iter == last ); ){
		_Ty& __ref_ = *( pArray + iter );
		if( !p( __ref_ ) )
			pArray[ first++ ] = std::move( __ref_ );
	}
	return first;
}

template < typename _Ty >
inline void range_set( _Ty *begIt, _Ty *endIt, _Ty val){
	while( !( begIt == endIt ) ) *begIt++ = val;
}
template < std::size_t _ArrayLength, typename _Ty, typename _UnaryPredicate >
std::size_t erase_if( _Ty ( &array )[ _ArrayLength ], _UnaryPredicate p, _Ty default_value ){
	std::size_t _Res { 0 };
	range_set( ( _Ty * )array +
					( _Res = remove_if( array, p )),
	           ( _Ty * )array + _ArrayLength,
			    default_value );
	return _Res;
}
template < typename _Ty, typename _UnaryPredicate >
std::size_t erase_if( _Ty *pArray, std::size_t _tN, _UnaryPredicate p, _Ty default_value ){
	std::size_t _Res { 0 };
	range_set( pArray +
						( _Res = remove_if( pArray, _tN, p ) ),
		       pArray + _tN,
			   default_value );
		return _Res;
}

template< typename RandomAccessIt, typename _BinaryPredicate>
void merge_sort(RandomAccessIt first, RandomAccessIt last, _BinaryPredicate p){
    if (last - first - 1 <= 0) return;
    RandomAccessIt middle =
		first + ( (last - first) >> 1 );
    merge_sort(first, middle, p);
    merge_sort(middle, last, p);
//    ::std::inplace_merge(first, middle, last, p);
  	::std::inplace_merge(first, middle, last, p);
}

template < typename _Ty,
		   typename _BinaryPredicate,
		   std::size_t _ArrayLength >
auto unique( _Ty ( &array )[ _ArrayLength ], _BinaryPredicate p )
->std::add_pointer< decltype(array[0]) >::type{
	using iterator =
		std::add_pointer< _Ty >::type;
	typedef signed ptrdiff_t;
	iterator first  = ( _Ty *)array,
			 last   = ( _Ty *)array + (ptrdiff_t)_ArrayLength,
			 result = first;
	while( !( ++first == last ) )
		if( !p( *result, *first )
		&&  !(result++ == first) )
		*result= std::move( *first );
	return ++result;
}
template < typename RandomAccessIt >
void random_shuffle( RandomAccessIt first, RandomAccessIt last ){
	typedef typename
	std::iterator_traits< RandomAccessIt >::difference_type diff_t;
	using ::std::swap; using ::std::rand;
	for( diff_t i { last - first - 1 }; i > 0; --i )
		swap(first[i], first[ std::rand() % ( i + 1) ] );
}

template<typename InputIt, typename OutputIt, typename UnaryOperation>
OutputIt transform(InputIt first1, InputIt last1,
                   OutputIt d_first,
				   UnaryOperation unary_op){
    while ( !( first1 != last1 ) )
        *d_first++ = unary_op(*first1++);
    return d_first;
}

template< std::size_t _ArrayLength, typename _Ty >
std::ostream& operator<<( std::ostream& out, _Ty ( &array )[ _ArrayLength ] ){
	std::copy( std::begin( array ),
			   std::end( array ),
			   std::ostream_iterator< _Ty >( out, "|") );
	return out;
}
static int increment { 0 };
int main( void ){
	int array[ 12 ] { 0, };
	::std::transform( ::std::cbegin( array ),
					::std::cend( array ),
					::std::begin( array ),
					[&]( int e ){
		return (increment++) % 4 + 1;
	});
	puts("initialized...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	random_shuffle( ::std::begin( array ), ::std::end( array ) );
	puts("\n\nrandom shuffled...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	merge_sort( std::begin( array ), ::std::end( array ) ,
	[&]( const int& v1, const int& v2 )->bool{ return v1 < v2; } );
	puts("\n\nsorted...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	int p = unique( array, [&]( const int& v1, const int& v2 )
	->bool{ return v1 == v2; } ) - ( int *)array;
	puts("\n\nunique processed..");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );

	erase_if( array + p, 12 - p, [&]( int& ){ return true; }, -1 );
	puts("\n\ntrail pait erased...");
	::std::cout << array << ::std::flush;
	::std::endl( ::std::cout );
	return 0;
}

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值