ループを使わずに配列の順序を逆にする
ループ
ループを使わずにと言われてもすぐに思いつかない場合はまずはそのループを使った実装を考えてみましょう
ループを使わないように変形するのはその後で構いません
template<typename _value_type,int _size> _value_type (&reverse_array( _value_type (&a)[_size] ))[_size]{ _value_type* _first = &a[0]; _value_type* _last = &a[_size-1]; while( _first < _last ){ _value_type temp = *_first; *_first = *_last; *_last = temp; ++_first; --_last; } return a; } template<typename _value_type,int _size> void print_array( const _value_type (&a)[_size] ){ debug_printf( "{" ); for( int n = 0; n < _size; ++n ){ if( n ){ debug_printf( "," ); } debug_printf( "%d", a[n] ); }; debug_printf( "}\n" ); } int main(){ int aaa[] = { 1,2,3,4,5,6,7,8,9,10 }; print_array( aaa ); print_array( reverse_array( aaa )); int bbb[] = { 1 }; print_array( bbb ); print_array( reverse_array( bbb )); int ccc[] = { 1,2,3 }; print_array( ccc ); print_array( reverse_array( ccc )); return 0; }
再帰
ループしているものをループを使わずにと言ったら再帰
template<typename _value_type,int _size> _value_type (&reverse_array( _value_type (&a)[_size] ))[_size]{ struct detail { typedef _value_type value_type; typedef _value_type* pointer; typedef _value_type& reference; static void callback( reference _first, reference _last ){ _value_type temp = _first; _first = _last; _last = temp; } static pointer enum_elements( pointer _first, pointer _last, void (*_callback)( reference, reference )){ if( _first < _last ){ _callback( *_first, *_last ); enum_elements( _first+1, _last-1, _callback ); } return _first; } }; detail::enum_elements( &a[0], &a[_size-1], &detail::callback ); return a; } template<typename _value_type,int _size> void print_array( const _value_type (&a)[_size] ){ struct detail { typedef _value_type value_type; typedef const _value_type* const_pointer; static void callback( const_pointer _first, const_pointer _last ){ if( _last - _first < _size ){ debug_printf( "," ); } debug_printf( "%d", *_first ); } static void enum_elements( const_pointer _first, const_pointer _last, void (*_callback)( const_pointer, const_pointer )){ if( _first < _last ){ _callback( _first, _last ); enum_elements( ++_first, _last, _callback ); } } }; debug_printf( "{" ); detail::enum_elements( &a[0], &a[_size], &detail::callback ); debug_printf( "}\n" ); } int main(){ int aaa[] = { 1,2,3,4,5,6,7,8,9,10 }; print_array( aaa ); print_array( reverse_array( aaa )); int bbb[] = { 1 }; print_array( bbb ); print_array( reverse_array( bbb )); int ccc[] = { 1,2,3 }; print_array( ccc ); print_array( reverse_array( ccc )); return 0; }
テンプレート
再帰条件がコンパイル時に決定できる再帰はテンプレートにできる
template<int lhs,int rhs> struct less_than_t { static const bool value = ( lhs < rhs ); }; template<typename _value_type,int _size,int _first = 0,int _last = _size-1,bool = less_than_t<_first,_last>::value> struct reverse_array_helper_t { static _value_type (&swap( _value_type (&a)[_size] ))[_size] { return a; } }; template<typename _value_type,int _size,int _first,int _last> struct reverse_array_helper_t<_value_type,_size,_first,_last,true> { static _value_type (&swap( _value_type (&a)[_size] ))[_size] { _value_type temp = a[_first]; a[_first] = a[_last]; a[_last] = temp; return reverse_array_helper_t<_value_type,_size,_first+1,_last-1>::swap( a ); } }; template<typename _value_type,int _size> _value_type (&reverse_array( _value_type (&a)[_size] ))[_size]{ return reverse_array_helper_t<_value_type,_size>::swap( a ); } template<int _size,int _offset> struct print_array_loop_helper_t { static const bool value = ( _offset < _size ); }; template<typename _value_type,int _size,int _offset = 0,bool = print_array_loop_helper_t<_size,_offset>::value> struct print_array_helper_t { static void print( const _value_type (&)[_size] ){ debug_printf( "}\n" ); } }; template<typename _value_type,int _size,int _offset> struct print_array_helper_t<_value_type,_size,_offset,true> { static void print( const _value_type (&a)[_size] ){ debug_printf( ",%d", a[_offset] ); print_array_helper_t<_value_type,_size,_offset+1>::print( a ); } }; template<typename _value_type,int _size> struct print_array_helper_t<_value_type,_size,0,true> { static void print( const _value_type (&a)[_size] ){ debug_printf( "{%d", a[0] ); print_array_helper_t<_value_type,_size,0+1>::print( a ); } }; template<typename _value_type,int _size> void print_array( const _value_type (&a)[_size] ){ print_array_helper_t<_value_type,_size>::print( a ); } int main(){ int aaa[] = { 1,2,3,4,5,6,7,8,9,10 }; print_array( aaa ); print_array( reverse_array( aaa )); int bbb[] = { 1 }; print_array( bbb ); print_array( reverse_array( bbb )); int ccc[] = { 1,2,3 }; print_array( ccc ); print_array( reverse_array( ccc )); return 0; }