Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- char A[] = { 'a', 'b', 'c' };
- size_t ORDER[] = { 1, 0, 2 };
- vector<char> vA(A, A + sizeof(A) / sizeof(*A));
- vector<size_t> vOrder(ORDER, ORDER + sizeof(ORDER) / sizeof(*ORDER));
- reorder_naive(vA, vOrder);
- // A is now { 'b', 'a', 'c' }
- void reorder_naive(vector<char>& vA, const vector<size_t>& vOrder)
- {
- assert(vA.size() == vOrder.size());
- vector vCopy = vA; // Can we avoid this?
- for(int i = 0; i < vOrder.size(); ++i)
- vA[i] = vCopy[ vOrder[i] ];
- }
- template< class T >
- void reorder(vector<T> &v, vector<size_t> const &order ) {
- for ( int s = 1, d; s < order.size(); ++ s ) {
- for ( d = order[s]; d < s; d = order[d] ) ;
- if ( d == s ) while ( d = order[d], d != s ) swap( v[s], v[d] );
- }
- }
- template< typename order_iterator, typename value_iterator >
- void reorder( order_iterator order_begin, order_iterator order_end, value_iterator v ) {
- typedef typename iterator_traits< value_iterator >::value_type value_t;
- typedef typename iterator_traits< order_iterator >::value_type index_t;
- typedef typename iterator_traits< order_iterator >::difference_type diff_t;
- diff_t remaining = order_end - 1 - order_begin;
- for ( index_t s = index_t(), d; remaining > 0; ++ s ) {
- for ( d = order_begin[s]; d > s; d = order_begin[d] ) ;
- if ( d == s ) {
- -- remaining;
- value_t temp = v[s];
- while ( d = order_begin[d], d != s ) {
- swap( temp, v[d] );
- -- remaining;
- }
- v[s] = temp;
- }
- }
- }
- template< typename order_iterator, typename value_iterator >
- void reorder_destructive( order_iterator order_begin, order_iterator order_end, value_iterator v ) {
- typedef typename iterator_traits< value_iterator >::value_type value_t;
- typedef typename iterator_traits< order_iterator >::value_type index_t;
- typedef typename iterator_traits< order_iterator >::difference_type diff_t;
- diff_t remaining = order_end - 1 - order_begin;
- for ( index_t s = index_t(); remaining > 0; ++ s ) {
- index_t d = order_begin[s];
- if ( d == (diff_t) -1 ) continue;
- -- remaining;
- value_t temp = v[s];
- for ( index_t d2; d != s; d = d2 ) {
- swap( temp, v[d] );
- swap( order_begin[d], d2 = (diff_t) -1 );
- -- remaining;
- }
- v[s] = temp;
- }
- }
- void REORDER(vector<char>& vA, vector<size_t>& vOrder)
- {
- assert(vA.size() == vOrder.size());
- // for all elements to put in place
- for( int i = 0; i < va.size() - 1; ++i )
- {
- // while the element i is not yet in place
- while( i != vOrder[i] )
- {
- // swap it with the element at its final place
- int alt = vOrder[i];
- swap( vA[i], vA[alt] );
- swap( vOrder[i], vOrder[alt] );
- }
- }
- }
- template <typename T>
- void reorder( std::vector<T> & data, std::vector<std::size_t> const & order )
- {
- std::vector<T> tmp; // create an empty vector
- tmp.reserve( data.size() ); // ensure memory and avoid moves in the vector
- for ( std::size_t i = 0; i < order.size(); ++i ) {
- tmp.push_back( data[order[i]] );
- }
- data.swap( tmp ); // swap vector contents
- }
- template <typename T>
- void reorder( std::vector<T> & data, std::vector<std::size_t> const & order )
- {
- for ( std::size_t i = 0; i < order.size(); ++i ) {
- std::size_t original = order[i];
- while ( i < original ) {
- original = order[original];
- }
- std::swap( data[i], data[original] );
- }
- }
- // Recursive function
- template<typename T>
- void REORDER(int oldPosition, vector<T>& vA,
- const vector<int>& vecNewOrder, vector<bool>& vecVisited)
- {
- // Keep a record of the value currently in that position,
- // as well as the position we're moving it to.
- // But don't move it yet, or we'll overwrite whatever's at the next
- // position. Instead, we first move what's at the next position.
- // To guard against loops, we look at vecVisited, and set it to true
- // once we've visited a position.
- T oldVal = vA[oldPosition];
- int newPos = vecNewOrder[oldPosition];
- if (vecVisited[oldPosition])
- {
- // We've hit a loop. Set it and return.
- vA[newPosition] = oldVal;
- return;
- }
- // Guard against loops:
- vecVisited[oldPosition] = true;
- // Recursively re-order the next item in the sequence.
- REORDER(newPos, vA, vecNewOrder, vecVisited);
- // And, after we've set this new value,
- vA[newPosition] = oldVal;
- }
- // The "main" function
- template<typename T>
- void REORDER(vector<T>& vA, const vector<int>& newOrder)
- {
- // Initialise vecVisited with false values
- vector<bool> vecVisited(vA.size(), false);
- for (int x = 0; x < vA.size(); x++)
- {
- REORDER(x, vA, newOrder, vecVisited);
- }
- }
- vector<char> REORDER(const vector<char>& vA, const vector<size_t>& vOrder)
- {
- assert(vA.size() == vOrder.size());
- vector<char> vCopy(vA.size());
- for(int i = 0; i < vOrder.size(); ++i)
- vCopy[i] = vA[ vOrder[i] ];
- return vA;
- }
- void REORDER(vector<char>& vA, const vector<size_t>& vOrder)
- {
- assert(vA.size() == vOrder.size());
- for(int i = 0; i < vOrder.size(); ++i)
- if (i < vOrder[i])
- swap(vA[i], vA[vOrder[i]]);
- }
Add Comment
Please, Sign In to add comment