I\'m looking for a way to rotate a string in c++. I spend all of my time in python, so my c++ is very rusty.
Here is what I want it to do: if I have a strin
this code worked for me:
using namespace std;
string StrRotate(string &s, int nLeft)
{
int size = s.size();
nLeft %= size;
if(nLeft == 0) return s;
string after = s.substr(0, nLeft);
string before = s.substr(nLeft, size - nLeft);
return before + after;
}
I recommend std::rotate:
std::rotate(s.begin(), s.begin() + 1, s.end());
If you don't want these in-place solutions, then your python code can be directly translated to C++, with a bit of extra code to deal with the fact that index out of bounds is bad news in C++.
s[1:] --> s.substr(1);
s[:1] --> s[0]; // s[0] is a char not a string, but that's good enough
So,
std::string rotate(const std::string &s) {
if (s.size() > 0) return s.substr(1) + s[0];
return s;
}
This isn't the most efficient: it will almost certainly do more string creation than the minimum possible. But you don't usually need the most efficient, and you have reserve
and append
if you want to do concatenation without unnecessary allocation.
Here is code in C that does not use any external functions: It rotates the string in-place both forward and backwards by any value no matter how big.
int stringRotate(int value)
{
unsigned long I,J,K;
unsigned long index0;
unsigned long temp1,temp2;
unsigned long length;
length = stringLength;
if (value < 0)
value = length - ((0 - value) % length);
if (value > length)
value = value % length;
J = 0;
index0 = J;
temp1 = stringData[J];
for (I = 0;I < length;I++)
{
K = (J + value) % length;
temp2 = stringData[K];
stringData[K] = temp1;
J = K;
temp1 = temp2;
if (J == index0)
{
J++;
index0 = J;
temp1 = stringData[J];
}
}
return 1;
}
To rotate the string both forward and backwards would be a bit tedious so it is better to only do forward rotate and calculate the correct value for backwards.Also if the rotation value is more than the length of the string, then we can just clip it since the result would be the same anyway.
value = length - ((0 - value) % length) : means if the rotation value is negative, then set the value to the length of the string, minus the positive result of the remainder of dividing the value by the length of the string. For example: rotating a string of length 10 by -9 positions would be the same as rotating by +1. Rotating the same string by -19 positions would also be the same as rotating by plus one. value = value % length : means if the positive value is more than the string length, then divide by the string length and take the remainder. The result would be the same as if we just did it the long way.
To do the rotation in place, we are going to need to jump by the value of of the rotation to swap characters that are that far apart. We start at position zero, move forward by the rotation value and continue jumping by that amount. if we go past the end of the string, we simply wrap back to the beginning. The problem is that if the value is an even number, we will end up right where we started and will miss all the odd characters. The variable index0 is there to indicate where we started from. If we end up back at this index then we need to move forward by one index position and continue jumping. We continue to do this until all the characters are swapped At this point we need two temporary variables to do the swapping in place. J is the starting position. We move the character at index J to the first temporary variable. Now we loop I to the length of the string. K is the destination index, J plus the rotation value Wrapped around the end if needed. Move the character at index K to the second temporary variable. Put the character from index J into index K using the first temporary variable. By the way the reason why we do not just move the character directly from index J into index K is because of the last part of the loop, the indices may change in between loops but the characters in temp1 should not. Now we exchange the temp1 with temp2. This last part is for where the value is an even number and we are back where we started. This will happen by times the rotation value minus one. increment index J by one and reset the starting values. Loop until done.
A video demonstration can be found here: https://www.youtube.com/watch?v=TMzaO2WzR24
Is doing it in place a requirement?
If not, you're probably best off taking a substring of all but the first char, and then appending the first char to the end.
Here's a relatively simple way:
void RotateStringInPlace(char buffer[])
{
// Get the length of the string.
int len = strlen(buffer);
if (len == 0) {
return;
}
// Save the first character, it's going to be overwritten.
char tmp = buffer[0];
// Slide the rest of the string over by one position.
memmove(&buffer[0], &buffer[1], len - 1);
// Put the character we saved from the front of the string in place.
buffer[len - 1] = tmp;
return;
}
Note that this will modify the buffer in place.