I have a working rotating function going for my "items" int array. The code below gets it done, except that im transferring values out unnecessarily. Im trying to acheive the "inplace" rotation. What I mean by that is where the ptrs would increment or decrement instead of grabbing values out of the array..By which I need to "up" the efficiency level in that way for this method..Any Suggestions?
void quack::rotate(int nRotations)
{
if ( count <= 1 ) return;
else // make sure our ptrs are where we want them.
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt;
}
for (int temp = 0; nRotations != 0;)
{
if ( nRotations > 0 )
{
temp = *intFrontPtr;
*intFrontPtr = *intBackPtr;
*intBackPtr = temp; // Connect temps for the rotation
--intBackPtr; // Move left [...<-] into the array
}
else if ( nRotations < 0 )
{
temp = *intBackPtr;
*intBackPtr = *intFrontPtr;
*intFrontPtr = temp; // Connect temps for the rotation
++intFrontPtr; // Move right [->...] into the array
}
if ( intBackPtr == &items[0].myInt ||
intFrontPtr == &items[count-1].myInt )
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt; // need to re-set
if ( nRotations > 0 ) nRotations--; // Which ways did we rotate?
else nRotations++;
}
}
}
Oh yes, Im trying to practice c++ and know their are many functions floating around that are programmed to do this already...Im trying to "build my own". I think i've got it down syntactically, but the efficiency is always where i struggle. As, a novice, I would greatly appreciate critisim towards this aspect..
You can leave the data in place, and have a "base index" member to indicate where the array should start. You then need to use this to adjust the index when accessing the array. The array itself should be private, and only accessed through accessor functions that do the adjustment. Something like this:
although I'd call it something like
RotatableArray
, rather thanquack
.There are many ways to do array rotation by d places.
The link below is from Programming Pearls pdf. Check this out. Explained very clearly with code.
http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf
As usual, if you really have to physically rotate the elements, the correct answer for C++ would be to use
std::rotate
, which does exactly what you want to do.If you have to implement it manually (as a practice assignment), take a look at these slides for algorithms from John Bentley's "Programming Pearls".
I may have an alternate solution to rotating the array inline. Rather than the old trick of reversing sets of elements, as proposed earlier, this approach works as follows:
Initialization:
(Note q = amount to shift left, n = length of array)
Loop on i=0 to n-1, where n = length of array
The following may help explain how this works.
Example, rotate to the left by 2 characters:
a b c d e f g
c d e f g a b
As you can see, this requires no more than n iterations, so it is linear time algorithm that also rotates inline (requires no additional storage other than the few temporary variables).
Here is a function that implements the above algorithm so you can try it out:
doing the rotations one by one is really not the way to go. If you are doing anything more than 2 or 3 rotations it gets really slow really quick.
edit: as a final thought... putting the elements in a (double) linked 'looped' list (so the final element points to the first), would require for a rotate to only move the head pointer a few elements. (The head pointer being a pointer to indicate which element in the looped list is the beginning).
this is by far the quickest (and easiest) way to do a rotate on a list of elements
Really the way to do it is to use indexes instead of pointers.