Guest User

Untitled

a guest
Jun 17th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.22 KB | None | 0 0
  1. char A[] = { 'a', 'b', 'c' };
  2. size_t ORDER[] = { 1, 0, 2 };
  3.  
  4. vector<char> vA(A, A + sizeof(A) / sizeof(*A));
  5. vector<size_t> vOrder(ORDER, ORDER + sizeof(ORDER) / sizeof(*ORDER));
  6. reorder_naive(vA, vOrder);
  7. // A is now { 'b', 'a', 'c' }
  8.  
  9. void reorder_naive(vector<char>& vA, const vector<size_t>& vOrder)
  10. {
  11. assert(vA.size() == vOrder.size());
  12. vector vCopy = vA; // Can we avoid this?
  13. for(int i = 0; i < vOrder.size(); ++i)
  14. vA[i] = vCopy[ vOrder[i] ];
  15. }
  16.  
  17. template< class T >
  18. void reorder(vector<T> &v, vector<size_t> const &order ) {
  19. for ( int s = 1, d; s < order.size(); ++ s ) {
  20. for ( d = order[s]; d < s; d = order[d] ) ;
  21. if ( d == s ) while ( d = order[d], d != s ) swap( v[s], v[d] );
  22. }
  23. }
  24.  
  25. template< typename order_iterator, typename value_iterator >
  26. void reorder( order_iterator order_begin, order_iterator order_end, value_iterator v ) {
  27. typedef typename iterator_traits< value_iterator >::value_type value_t;
  28. typedef typename iterator_traits< order_iterator >::value_type index_t;
  29. typedef typename iterator_traits< order_iterator >::difference_type diff_t;
  30.  
  31. diff_t remaining = order_end - 1 - order_begin;
  32. for ( index_t s = index_t(), d; remaining > 0; ++ s ) {
  33. for ( d = order_begin[s]; d > s; d = order_begin[d] ) ;
  34. if ( d == s ) {
  35. -- remaining;
  36. value_t temp = v[s];
  37. while ( d = order_begin[d], d != s ) {
  38. swap( temp, v[d] );
  39. -- remaining;
  40. }
  41. v[s] = temp;
  42. }
  43. }
  44. }
  45.  
  46. template< typename order_iterator, typename value_iterator >
  47. void reorder_destructive( order_iterator order_begin, order_iterator order_end, value_iterator v ) {
  48. typedef typename iterator_traits< value_iterator >::value_type value_t;
  49. typedef typename iterator_traits< order_iterator >::value_type index_t;
  50. typedef typename iterator_traits< order_iterator >::difference_type diff_t;
  51.  
  52. diff_t remaining = order_end - 1 - order_begin;
  53. for ( index_t s = index_t(); remaining > 0; ++ s ) {
  54. index_t d = order_begin[s];
  55. if ( d == (diff_t) -1 ) continue;
  56. -- remaining;
  57. value_t temp = v[s];
  58. for ( index_t d2; d != s; d = d2 ) {
  59. swap( temp, v[d] );
  60. swap( order_begin[d], d2 = (diff_t) -1 );
  61. -- remaining;
  62. }
  63. v[s] = temp;
  64. }
  65. }
  66.  
  67. void REORDER(vector<char>& vA, vector<size_t>& vOrder)
  68. {
  69. assert(vA.size() == vOrder.size());
  70.  
  71. // for all elements to put in place
  72. for( int i = 0; i < va.size() - 1; ++i )
  73. {
  74. // while the element i is not yet in place
  75. while( i != vOrder[i] )
  76. {
  77. // swap it with the element at its final place
  78. int alt = vOrder[i];
  79. swap( vA[i], vA[alt] );
  80. swap( vOrder[i], vOrder[alt] );
  81. }
  82. }
  83. }
  84.  
  85. template <typename T>
  86. void reorder( std::vector<T> & data, std::vector<std::size_t> const & order )
  87. {
  88. std::vector<T> tmp; // create an empty vector
  89. tmp.reserve( data.size() ); // ensure memory and avoid moves in the vector
  90. for ( std::size_t i = 0; i < order.size(); ++i ) {
  91. tmp.push_back( data[order[i]] );
  92. }
  93. data.swap( tmp ); // swap vector contents
  94. }
  95.  
  96. template <typename T>
  97. void reorder( std::vector<T> & data, std::vector<std::size_t> const & order )
  98. {
  99. for ( std::size_t i = 0; i < order.size(); ++i ) {
  100. std::size_t original = order[i];
  101. while ( i < original ) {
  102. original = order[original];
  103. }
  104. std::swap( data[i], data[original] );
  105. }
  106. }
  107.  
  108. // Recursive function
  109. template<typename T>
  110. void REORDER(int oldPosition, vector<T>& vA,
  111. const vector<int>& vecNewOrder, vector<bool>& vecVisited)
  112. {
  113. // Keep a record of the value currently in that position,
  114. // as well as the position we're moving it to.
  115. // But don't move it yet, or we'll overwrite whatever's at the next
  116. // position. Instead, we first move what's at the next position.
  117. // To guard against loops, we look at vecVisited, and set it to true
  118. // once we've visited a position.
  119. T oldVal = vA[oldPosition];
  120. int newPos = vecNewOrder[oldPosition];
  121. if (vecVisited[oldPosition])
  122. {
  123. // We've hit a loop. Set it and return.
  124. vA[newPosition] = oldVal;
  125. return;
  126. }
  127. // Guard against loops:
  128. vecVisited[oldPosition] = true;
  129.  
  130. // Recursively re-order the next item in the sequence.
  131. REORDER(newPos, vA, vecNewOrder, vecVisited);
  132.  
  133. // And, after we've set this new value,
  134. vA[newPosition] = oldVal;
  135. }
  136.  
  137. // The "main" function
  138. template<typename T>
  139. void REORDER(vector<T>& vA, const vector<int>& newOrder)
  140. {
  141. // Initialise vecVisited with false values
  142. vector<bool> vecVisited(vA.size(), false);
  143.  
  144. for (int x = 0; x < vA.size(); x++)
  145. {
  146. REORDER(x, vA, newOrder, vecVisited);
  147. }
  148. }
  149.  
  150. vector<char> REORDER(const vector<char>& vA, const vector<size_t>& vOrder)
  151. {
  152. assert(vA.size() == vOrder.size());
  153. vector<char> vCopy(vA.size());
  154. for(int i = 0; i < vOrder.size(); ++i)
  155. vCopy[i] = vA[ vOrder[i] ];
  156. return vA;
  157. }
  158.  
  159. void REORDER(vector<char>& vA, const vector<size_t>& vOrder)
  160. {
  161. assert(vA.size() == vOrder.size());
  162. for(int i = 0; i < vOrder.size(); ++i)
  163. if (i < vOrder[i])
  164. swap(vA[i], vA[vOrder[i]]);
  165. }
Add Comment
Please, Sign In to add comment