Rotate () function analysis of STL source code analysis
What is the rotate () function capable of?
Http://www.cplusplus.com/reference/algorithm/rotate/?kw=rotate
The above is only approximate, the source code is given below:
Rotate and rotate_copy, and their auxiliary functionstemplate <class _euclideanringelement>_ Euclideanringelement __GCD (_euclideanringelement __m, _euclideanringelement __n) {while (__n!) = 0) {_euclideanringelement __t = __m% __n; __m = __n; __n = __t; } return __m;} Template <class _forwarditer, class _distance>_forwarditer __rotate (_forwarditer __first, _FORW Arditer __middle, _forwarditer __last, _distance*, Forward_ Iterator_tag) {if (__first = = __middle) return __last; if (__last = = __middle) return __first; _forwarditer __first2 = __middle; Do {swap (*__first++, *__first2++); if (__first = = __middle) __middle = __first2; } while (__first2! = __last); _forwarditer __new_middle = __first; __first2 = __middle; while (__first2! = __last) {swap (*__first++, *__first2++); if (__first = = __middle) __middle = __firsT2; else if (__first2 = = __last) __first2 = __middle; } return __new_middle;} Template <class _bidirectionaliter, class _distance>_bidirectionaliter __rotate (_bidirectionaliter __first, _bidirectionaliter __middle, _bidirectionaliter __last, _distance*, Bidirectional_iterator_tag) {__stl_requires (_bidirectionaliter, _mutable_b Idirectionaliterator); if (__first = = __middle) return __last; if (__last = = __middle) return __first; __reverse (__first, __middle, Bidirectional_iterator_tag ()); __reverse (__middle, __last, Bidirectional_iterator_tag ()); while (__first! = __middle && __middle! = __last) Swap (*__first++, *--__last); if (__first = = __middle) {__reverse (__middle, __last, Bidirectional_iterator_tag ()); return __last; } else {__reverse (__first, __middle, Bidirectional_iterator_tag ()); return __first; }}/* all ElemEnts. |...front. | ... | ^ 0 Offset ^ Middle ^ last*/template <class _randomaccessiter, Class _distance, class _tp>_randomaccessiter _ _rotate (_randomaccessiter __first, _randomaccessiter __middle, _random Accessiter __last, _distance *, _TP *) {__stl_requires (_randomaccessiter, _mutable_randomacces Siterator); _distance __n = __last-__first; The number of all elements _distance __k = __middle-__first; The front elements _distance __l = __n-__k; The back elements _randomaccessiter __result = __first + (__last-__middle); if (__k = = 0) return __last; else if (__k = = __l) {swap_ranges (__first, __middle, __middle); return __result; } _distance __d = __GCD (__n, __k); for (_distance __i = 0; __i < __d; __i++) {_tp __tmp = *__first; _randomaccessiter __p = __first; if (__k < __l) {/* In this case, elements of the BAck part was more than the front ' s. */for (_distance __j = 0; __j < __l/__d; __j++) {if (__p > __first + __l) {*__p = * (__p-__) L); __p-= __l; } *__p = * (__p + __k); __p + = __k; }} else {for (_distance __j = 0; __j < __k/__d-1; __j + +) {if (__p < __last-__k) { *__p = * (__p + __k); __p + = __k; } *__p = * (__p-__l); __p-= __l; }} *__p = __tmp; ++__first; } return __result;}
Want to debug themselves, anyway the code is not long, copy a little modification can be used.
Seriously read the above source code, I will find that the changes I made very very small.
I added a macro definition switch, DEBUG, wrote a show_data function, easy to see the changes in the data
/************************************************programmer:eofe-mail:[email protected]date : 2015.04.02file:rotate.cpp*************************************************/#include <iostream> #include <vector> #include <algorithm> #define debugusing namespace Std;int __gcd (int __m, int __n) {int __t = 0;while (__ n! = 0) {__t = __m% __n;__m = __n;__n = __t;} return __m;} void Show_data (Vector<int>::iterator first, Vector<int>::iterator last) {for (; first! = Last; first++) {cout << *first << "";} cout << Endl << Endl;} /* all elements. |...front. | ... | ^ 0 Offset ^ Middle ^ last*/void My_rotate (Vector<int>::iterator __first, Vector<int>::it Erator __middle, Vector<int>::iterator __last) {int __n = __last-__first;//The number of all Elem Entsint __k = __middle-__first; The front elementsint __l = __n-__k; The back elementsif (__k = = 0) return; int __d = __GCD (__n, __k); #ifdef debugvector<int>::iterator start = __first;cout << "The original data:" << endl;s How_data (Start, __last), #endifvector <int>::iterator __p;for (int __i = 0; __i < __d; __i++) {int __tmp = *__first ; __p = __first;if (__k < __l) {/* In this case, elements of the "back" is more than the front ' s.*/for (int __j = 0; __j < __l/__d; __j++) {/***it ' s so fantastic!! */if (__p > __first + __l) {*__p = * (__p-__l); __p-= __l;} *__p = * (__p + __k) __p + = __k; #ifdef debugcout << "I:" << __i << "J:" << __j << Endl;sho W_data (Start, __last), #endif}}else {for (int __j = 0; __j < __k/__d-1; __j++) {if (__p < __last-__k) {*__p = * (__p + __k); __p + = __k;} *__p = * (__p-__l); __p-= __l; #ifdef debugcout << "I:" << __i << "J:" << __j << endl;sh Ow_data (start, __last); #endif}}*__p = __tmp;++__first;} return;} int main () {vector<int> Myvector;//set some values;for (int i = 0; I < 9; i++) {myvector.push_back (i);} My_rotate (Myvector.begin (), Myvector.begin () + 3, Myvector.end ()), cout << "myvector contains:"; for (Vect Or<int>::iterator it = Myvector.begin (); It! = Myvector.end (); it++) {cout << "" << *it;} cout << Endl;return 0;}
Add the Show_data () it is very easy to perceptual first of all how the algorithm operation has a preliminary understanding.
The program author is very ingenious and does not use the extra memory, the rotate operation of the data in situ. STL authors, they're all Daniel.
Qaq I really feel I understand, but this place I do not know how to express the concise.
Why do you use GCD in that place? What is the specific meaning.
Pending Update ~
Rotate () function analysis of STL source code analysis