Reversing a string is a common task in programming, and C# provides several ways to accomplish it. Whether we need to reverse a string for sorting purposes, to improve search efficiency, or for any other reason, understanding how to perform this operation in C# is an essential skill.
In this article, we will examine several techniques to reverse a string in C# and compare their performance to help you choose the best approach for your specific use case.
Let’s start!
Application Setup
To explore ways to reverse a string in C#. let’s start by creating a console application using the Visual Studio Project wizard or the dotnet new console
command.
For each solution, we will create a method that takes a string as an argument and returns one, too.
Some of the techniques we propose involve creating a new string or data structure to hold the reversed characters, while others work by manipulating the existing string in place. The choice of technique may depend on the size of the string, the performance requirements, and the available memory. We explore different approaches in C#, discuss their tradeoffs, and compare their performance.
We’ll start by setting up a simple example to test against our methods:
var input = "abcdefg";
We construct a simple string using the first seven letters of the Latin alphabet and we expect to return the letters in reversed order: "gfedcba"
.
Use Array.Reverse() Method to Reverse a String
The first method to reverse a string we’ll look at is the Reverse()
method from the Array
class:
public string ArrayReverseString(string stringToReverse) { var charArray = stringToReverse.ToCharArray(); Array.Reverse(charArray); return new string(charArray); }
First, we convert the input string into a character array using the ToCharArray()
method provided by the string
class in C#. This method splits a string into its constituent characters and stores them in a char[]
.
Next, we use the Reverse()
method to reverse the order of the elements in the charArray
collection.
Finally, we convert the reversed charArray
back into a string
using the string constructor that takes an array of characters as input and we return it.
The result is the following:
Reversed String: gfedcba
As we expect, the result is the initial string’s characters in reverse order.
Enumerable Reverse() Extension Method for String Reversion
Our next solution uses the Reverse()
extension method of the Enumerable
class:
public string EnumerableReverseMethod(string stringToReverse) { return string.Concat(Enumerable.Reverse(stringToReverse)); }
The Enumerable.Reverse()
method takes a collection (in this case, a string) and returns an IEnumerable<char>
. Here, it represents a sequence of characters in reverse order.
To convert the reversed sequence of characters back into a string, we use the string.Concat()
method, which concatenates a sequence of characters into a single string.
In this case, we pass the reversed sequence to create a new string with the characters in reverse order.
Reverse a String With Recursion
Another option for reversing a string is to use recursion:
public string RecursiveStringReverseMethod(string stringToReverse) { if (stringToReverse.Length <= 1) return stringToReverse; return stringToReverse[^1] + RecursiveStringReverseMethod(stringToReverse[1..^1]) + stringToReverse[0]; }
Initially, we check if the length of the input string is less than or equal to 1. If this is the case, we simply return the input string.
Otherwise, we call the RecursiveStringReverseMethod()
method recursively, passing in the substring of the input string each time, excluding the first and last characters using the stringToReverse[1..^1]
object. We return the concatenation of the last character of the input substring
(stringToReverse[^1]
), the result of the recursive call, and the first character of the input string (stringToReverse[0]
).
In C# 8.0, two new concepts were introduced, Ranges and Indices. The [^1]
is called a slice notation and represents an index relative to the end of the string. In other words, s[^1]
is equivalent to stringToReverse[stringToReverse.Length - 1]
, which accesses the last character of the string.
The [1..1^]
syntax specifies a range that starts at the second character and ends at the second-to-last character. The ^
symbol represents an index relative to the end of the string. In this case, 1^
means one index from the end of the string.
This effectively reverses the input string using recursion.
Reverse a String Using a Loop and XOR Operator
Now we will utilize the XOR operator within iterations to reverse our string:
public string ReverseXorMethod(string stringToReverse) { var charArray = stringToReverse.ToCharArray(); var len = stringToReverse.Length - 1; for (int i = 0; i < len; i++, len--) { charArray[i] ^= charArray[len]; charArray[len] ^= charArray[i]; charArray[i] ^= charArray[len]; } return new string(charArray); }
First, we convert the string into a char[]
and initialize an integer variable len
to the length of the input string minus one.
We use a loop to swap the characters at the beginning and end of the charArray
, iterating from the start of the array to the middle. In each iteration of the loop, we perform three steps using XOR swapping to swap the characters at i
and len
index. The ^=
operator is the XOR assignment operator. It performs the XOR operation on the two operands and assigns the result to the left operand.
Once the loop completes the iterations, the charArray
contains the reversed string. Finally, we return a new string from the reversed charArray
.
Use Stack to Reverse a String
Next, we can use the Stack class, which is a last-in, first-out (LIFO) stack of objects, to reverse a string:
public string StackReverseMethod(string stringToReverse) { var resultStack = new Stack<char>(); foreach (char c in stringToReverse) { resultStack.Push(c); } var sb = new StringBuilder(); while (resultStack.Count > 0) { sb.Append(resultStack.Pop()); } return sb.ToString(); }
Here, we iterate the input string stringToReverse
character by character using a foreach
loop, and we push each character onto a resultStack
stack. This means that we add the characters to the stack in reverse order, effectively reversing the string.
We create a new StringBuilder object to construct the reversed string by popping characters from the stack and appending them to the StringBuilder
. The while
loop continues to pop characters from the stack and append them to the StringBuilder
until there are no more characters left in the stack.
Finally, we return the reversed string by calling the ToString()
method on the StringBuilder
object.
StringBuilder Method to Reverse a String
Alternatively, we can use the StringBuilder
class directly to reverse a string:
public string StringBuilderReverseMethod(string stringToReverse) { var sb = new StringBuilder(stringToReverse.Length); for (int i = stringToReverse.Length - 1; i >= 0; i--) { sb.Append(stringToReverse[i]); } return sb.ToString(); }
First, we create a new StringBuilder
object with an initial capacity equal to the length of the input string stringToReverse
. With this, we ensure that the StringBuilder
has enough space to hold the entire reversed string without needing to resize the buffer.
Next, we iterate over the characters in the input string in reverse order using a for
loop. In each iteration of the loop, the method appends the current character using the Append()
method. This effectively adds the characters to the StringBuilder
in reverse order, so that the final result is the desired one.
Finally, we return the string by calling the ToString()
method on the StringBuilder
object.
Use Create() Method to Create a String in Reverse Order
The Create()
extension method of the string
class can be used for the same purpose:
public string StringCreateMethod(string stringToReverse) { return string.Create(stringToReverse.Length, stringToReverse, (chars, state) => { state.AsSpan().CopyTo(chars); chars.Reverse(); }); }
Here, we use the string.Create()
method to create a new string that is a reversed version of the input string stringToReverse
. The string.Create()
method takes a length, a state object, and a callback function as parameters. It creates a new string of specified length and passes it to the callback function, along with the state object. The callback function is responsible for initializing the string and returning it.
In this method, the state object is the input stringToReverse
string, which is passed to the string.Create()
method as the second argument. We define the callback function as an anonymous method that takes two parameters: chars
and state
. The chars
object is a span of characters that represents the newly created string, and the state
is the original input string.
The first line of the callback function copies the characters of the input string to the new string using the CopyTo()
method of the Span<char>
struct. This initializes the new string to be the same as the input string.
The second line of the callback function reverses the order of the characters in the chars
object using the Reverse
method of the Span<char>
struct. This effectively reverses the order of the characters in the new string, giving us our final reversed string.
LINQ Reverse() Extension Method
The last solution we’ll look at uses the built-in Reverse()
extension method of string
class:
public string StringExtensionReverseMethod(string stringToReverse) { return new string(stringToReverse.Reverse().ToArray()); }
Here, we use the LINQ Reverse()
extension method and the ToArray()
method to create a new string that is a reversed version of the input string stringToReverse
.
We use the string
constructor to create a new string from the reversed character array and we return it.
Special Characters Reversion With TextElementEnumerator
Sometimes we need to manipulate a string consisting of combining characters or surrogate pairs. These strings do not have a valid representation in Unicode. In this case, we cannot handle them character by character, as they consist of a sequence of several Unicode values.
For example, each character of a music notes collection (e.g. 𝅗𝅥𝄞𝅘𝅥𝅮𝅘𝅥𝅯) is a surrogate pair. We use the following approach to reverse it:
public string TextElementEnumeratorMethod(string stringToReverse) { return string.Create(stringToReverse.Length, stringToReverse, (chars, val) => { var valSpan = val.AsSpan(); var en = StringInfo.GetTextElementEnumerator(val); en.MoveNext(); var start = en.ElementIndex; var pos = chars.Length; while (en.MoveNext()) { var next = en.ElementIndex; var len = next - start; valSpan[start..next].CopyTo(chars[(pos - len)..pos]); pos -= len; start = next; } if (start != 0) valSpan[start..].CopyTo(chars[0..pos]); }); }
We use the string.Create()
method to efficiently create a new string with a specified length and content. The chars
parameter of the Create()
method is a span of characters to write to. The val
parameter is the value of the input string.
We create a TextElementEnumerator object using the StringInfo.GetTextElementEnumerator()
method, passing in the val
parameter but this time as Span since it will increase the performance of this approach compared to the same approach without it. This object allows us to enumerate over the text elements of val
.
Then, we iterate over the text elements in reverse order, copying each one to the new string.
First, we get the index of the current text element using the ElementIndex
property of the TextElementEnumerator
, and we calculate the length of the text element by subtracting the index of the previous text element.
Next, we use the CopyTo()
method to copy the text element to the appropriate position in the new string, which is given by the chars
span. To calculate its position, we use the pos
variable, which starts at the end of the new string and is decremented by the length of each text element.
Finally, if there are any remaining characters in the val
variable after all the text elements have been processed, the method copies them to the beginning of the new string.
What’s the Fastest Way to Reverse a String in C#?
Let’s evaluate these methods to find the most efficient one with the benchmark class. First, let’s create a method to generate a random string:
public static string GenerateText() { var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var random = new Random(); var length = 64; var builder = new StringBuilder(length); for (int i = 0; i < length; ++i) { var index = random.Next(alphabet.Length); builder.Append(alphabet[index]); } return builder.ToString(); }
Here, we generate a random string of characters by selecting characters from a pre-defined set. The set includes upper and lower case letters of the English alphabet and numeric digits.
Now we’re ready to run and analyze our benchmark results:
| Method | Mean | Error | StdDev | Rank | |---------------------------------------- |------------:|----------:|----------:|-----:| | UsingStringCreateMethod | 29.12 ns | 0.221 ns | 0.207 ns | 1 | | UsingArrayReverseString | 43.41 ns | 0.874 ns | 0.935 ns | 2 | | UsingReverseXorMethod | 90.88 ns | 1.657 ns | 2.322 ns | 3 | | UsingStringBuilderReverseMethod | 188.03 ns | 3.429 ns | 3.040 ns | 4 | | UsingStackReverseMethod | 575.88 ns | 8.609 ns | 8.456 ns | 5 | | UsingStringExtensionReverseMethod | 637.23 ns | 12.507 ns | 12.844 ns | 6 | | UsingEnumerableReverseMethod | 933.08 ns | 17.696 ns | 18.172 ns | 7 | | UsingRecursiveStringReverseMethod | 1,670.41 ns | 32.406 ns | 47.500 ns | 8 | | UsingTextElementEnumeratorReverseMethod | 2,253.07 ns | 17.249 ns | 16.135 ns | 9 |
We can see that when it comes to reversing a string, the StringCreateMethod()
method is the most efficient in terms of speed.
The StringCreateMethod()
method is the fastest because it takes advantage of Span<T>
and directly accesses the memory buffer of the original string, rather than creating a new copy of it. By using the string.Create()
method and a user-defined delegate that operates on a Span<T>
, we can efficiently initialize the reversed string in the same memory buffer as the original string.
This avoids the overhead of allocating a new string and copying the characters into it, making the StringCreateMethod()
method option faster than the other methods that create new copies of the string or using a loop.
Moreover, we observe that the ArrayReverseString()
method is similarly efficient. This is because the character array is directly modified in place without creating a new object.
In contrast, the RecursiveStringReverseMethod()
method has poor results as each recursive call to the method involves multiple string concatenations to build the final reversed string.
Regarding the TextElementEnumeratorMethod()
method, we’ve tested it and found that for the increased string size, the efficiency of this method grows and even gets better than the recursive one. It is worth mentioning though, that TextElementEnumeratorMethod()
method solves the problem of reversing a string including characters that combine Unicode values and not usual characters.
Conclusion
In this article, we examined various different methods that allow us to reverse a string. This included looking at a method that deals with combining or surrogate characters. Then, we evaluated our solutions in terms of performance and efficiency, determining which was the best choice for our requirements.