While writing a new article, I was fiddling around with some really old code, and stumbled across a method I wrote four years ago. It dealt with several methods for reversing a string
, and it lived in a "global" class that contains a lot of little methods that makes my day-to-day development efforts a little easier.
Well, never one to let an opportunity to possibly screw up some otherwise working code go to waste, I decided to muck around by making the existing method an extension method, and adding a second one to handle StringBuilder
objects. The existing string
object method goes like this:
public static class ExtensionMethods
{
public static string Reverse(this string text)
{
if (text.Length > 1)
{
int pivotPos = text.Length / 2;
for (int i = 0; i < pivotPos; i++)
{
text = text.Insert(text.Length - i, text.Substring(i, 1)).Remove(i, 1);
text = text.Insert(i, text.Substring
(text.Length - (i + 2), 1)).Remove(text.Length - (i + 1), 1);
}
return text;
}
}
}
The whole point was to perform the operation in as little time as possible, and the best way to do that (as far as I could see) was to determine how many character swaps had to be performed (text.Length / 2
), and then simply swap character on each end of the string
until it met in the middle. The really cool thing about this is that it works for string
s that have even AND odd lengths because in the event of an odd-length string
, the middle character doesn't need to change position. In our case, the division operation rounds down to the nearest whole integer value, which is perfect for what we want to do.
For the StringBuilder
object, I wanted to preserve its immutable nature, which meant I couldn't just use its ToString()
method, and call the previously described method, although that's certainly a viable and easy way to accomplish the same goal. Here's the code:
public static void Reverse(this StringBuilder text)
{
if (text.Length > 1)
{
int pivotPos = text.Length / 2;
for (int i = 0; i < pivotPos; i++)
{
int iRight = text.Length - (i + 1);
char rightChar = text[i];
char leftChar = text[iRight];
text[i] = leftChar;
text[iRight] = rightChar;
}
}
}
In the code above, we simply determine what positions we're at (i
and iRight
), retrieve the characters at those positions (rightChar
, and leftChar
), and put them in the appropriate location in the StringBuilder
's array. (Yes, I could have done the position math in the two places I needed it, but I wanted to be able to verify (in the debugger) that the values were what I wanted.
Usage
string text = "testing";
text = text.Reverse();
StringBuilder test = new StringBuilder(text);
test.Reverse();
I know, this ain't rocket science code, and you probably won't need it very often, but it's pretty handy to have around if you ever need to do this kind of thing.
NOTE: I want to point out that for the string
method, you could always do something like this:
public static string Reverse(this string text)
{
StringBuilder temp = new StringBuilder(text);
return temp.Reverse().ToString();
}
...which would be much more efficient in terms of memory use than doing this:
public static void Reverse(this StringBuilder text)
{
string temp = text.ToString().Reverse();
text.Replace(text.ToString(), temp);
}
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.
My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.