La mejor manera de invertir una cadena

Solo tuve que escribir una función de cadena inversa en C # 2.0 (es decir, LINQ no disponible) y se me ocurrió esto:

public string Reverse(string text) { char[] cArray = text.ToCharArray(); string reverse = String.Empty; for (int i = cArray.Length - 1; i > -1; i--) { reverse += cArray[i]; } return reverse; } 

Personalmente, no estoy loco por la función y estoy convencido de que hay una mejor manera de hacerlo. ¿Esta ahí?

 public static string Reverse( string s ) { char[] charArray = s.ToCharArray(); Array.Reverse( charArray ); return new string( charArray ); } 

Aquí hay una solución que invierte correctamente la cadena "Les Mise\u0301rables" como "selbare\u0301siM seL" . Esto debería selbarésiM seL igual que selbarésiM seL , no selbaŕesiM seL (tenga en cuenta la posición del acento), como sería el resultado de la mayoría de las implementaciones basadas en unidades de código ( Array.Reverse , etc.) o incluso puntos de código (invirtiendo con especial cuidado para los pares de sustitución )

 using System; using System.Collections.Generic; using System.Globalization; using System.Linq; public static class Test { private static IEnumerable GraphemeClusters(this string s) { var enumerator = StringInfo.GetTextElementEnumerator(s); while(enumerator.MoveNext()) { yield return (string)enumerator.Current; } } private static string ReverseGraphemeClusters(this string s) { return string.Join("", s.GraphemeClusters().Reverse().ToArray()); } public static void Main() { var s = "Les Mise\u0301rables"; var r = s.ReverseGraphemeClusters(); Console.WriteLine(r); } } 

(Y en vivo ejecutando el ejemplo aquí: https://ideone.com/DqAeMJ )

Simplemente usa la API de .NET para iteración de clúster de grafema , que ha estado allí desde siempre, pero parece un poco “oculta” de la vista.

Esto se está convirtiendo en una pregunta sorprendentemente difícil.

Yo recomendaría utilizar Array.Reverse para la mayoría de los casos, ya que está codificado de forma nativa y es muy fácil de mantener y comprender.

Parece superar a StringBuilder en todos los casos que probé.

 public string Reverse(string text) { if (text == null) return null; // this was posted by petebob as well char[] array = text.ToCharArray(); Array.Reverse(array); return new String(array); } 

Hay un segundo enfoque que puede ser más rápido para ciertas longitudes de cadena que usa Xor .

  public static string ReverseXor(string s) { if (s == null) return null; char[] charArray = s.ToCharArray(); int len = s.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); } 

Nota: si desea admitir el juego de caracteres Unicode UTF16 completo, lea esto . Y usa la implementación allí en su lugar. Se puede optimizar aún más mediante el uso de uno de los algoritmos anteriores y ejecutando a través de la cadena para limpiarlo después de que los caracteres se invierten.

Aquí hay una comparación de rendimiento entre el método StringBuilder, Array.Reverse y Xor.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; namespace ConsoleApplication4 { class Program { delegate string StringDelegate(string s); static void Benchmark(string description, StringDelegate d, int times, string text) { Stopwatch sw = new Stopwatch(); sw.Start(); for (int j = 0; j < times; j++) { d(text); } sw.Stop(); Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times); } public static string ReverseXor(string s) { char[] charArray = s.ToCharArray(); int len = s.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); } public static string ReverseSB(string text) { StringBuilder builder = new StringBuilder(text.Length); for (int i = text.Length - 1; i >= 0; i--) { builder.Append(text[i]); } return builder.ToString(); } public static string ReverseArray(string text) { char[] array = text.ToCharArray(); Array.Reverse(array); return (new string(array)); } public static string StringOfLength(int length) { Random random = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)))); } return sb.ToString(); } static void Main(string[] args) { int[] lengths = new int[] {1,10,15,25,50,75,100,1000,100000}; foreach (int l in lengths) { int iterations = 10000; string text = StringOfLength(l); Benchmark(String.Format("String Builder (Length: {0})", l), ReverseSB, iterations, text); Benchmark(String.Format("Array.Reverse (Length: {0})", l), ReverseArray, iterations, text); Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text); Console.WriteLine(); } Console.Read(); } } } 

Aquí están los resultados:

 26251 Ticks String Builder (Length: 1) : called 10000 times. 33373 Ticks Array.Reverse (Length: 1) : called 10000 times. 20162 Ticks Xor (Length: 1) : called 10000 times. 51321 Ticks String Builder (Length: 10) : called 10000 times. 37105 Ticks Array.Reverse (Length: 10) : called 10000 times. 23974 Ticks Xor (Length: 10) : called 10000 times. 66570 Ticks String Builder (Length: 15) : called 10000 times. 26027 Ticks Array.Reverse (Length: 15) : called 10000 times. 24017 Ticks Xor (Length: 15) : called 10000 times. 101609 Ticks String Builder (Length: 25) : called 10000 times. 28472 Ticks Array.Reverse (Length: 25) : called 10000 times. 35355 Ticks Xor (Length: 25) : called 10000 times. 161601 Ticks String Builder (Length: 50) : called 10000 times. 35839 Ticks Array.Reverse (Length: 50) : called 10000 times. 51185 Ticks Xor (Length: 50) : called 10000 times. 230898 Ticks String Builder (Length: 75) : called 10000 times. 40628 Ticks Array.Reverse (Length: 75) : called 10000 times. 78906 Ticks Xor (Length: 75) : called 10000 times. 312017 Ticks String Builder (Length: 100) : called 10000 times. 52225 Ticks Array.Reverse (Length: 100) : called 10000 times. 110195 Ticks Xor (Length: 100) : called 10000 times. 2970691 Ticks String Builder (Length: 1000) : called 10000 times. 292094 Ticks Array.Reverse (Length: 1000) : called 10000 times. 846585 Ticks Xor (Length: 1000) : called 10000 times. 305564115 Ticks String Builder (Length: 100000) : called 10000 times. 74884495 Ticks Array.Reverse (Length: 100000) : called 10000 times. 125409674 Ticks Xor (Length: 100000) : called 10000 times. 

Parece que Xor puede ser más rápido para cadenas cortas.

Si la cadena contiene datos Unicode (estrictamente hablando, caracteres que no son BMP), los otros métodos que se han publicado los corromperán, porque no se puede cambiar el orden de las unidades de código sustituto alto y bajo al invertir la cadena. (Más información sobre esto se puede encontrar en mi blog ).

El siguiente ejemplo de código invertirá correctamente una cadena que contenga caracteres que no sean BMP, por ejemplo, “\ U00010380 \ U00010381” (Letra Ugarítica, Alpa, Carta Ugarítica Beta).

 public static string Reverse(this string input) { if (input == null) throw new ArgumentNullException("input"); // allocate a buffer to hold the output char[] output = new char[input.Length]; for (int outputIndex = 0, inputIndex = input.Length - 1; outputIndex < input.Length; outputIndex++, inputIndex--) { // check for surrogate pair if (input[inputIndex] >= 0xDC00 && input[inputIndex] <= 0xDFFF && inputIndex > 0 && input[inputIndex - 1] >= 0xD800 && input[inputIndex - 1] <= 0xDBFF) { // preserve the order of the surrogate pair code units output[outputIndex + 1] = input[inputIndex]; output[outputIndex] = input[inputIndex - 1]; outputIndex++; inputIndex--; } else { output[outputIndex] = input[inputIndex]; } } return new string(output); } 

Desde arriba 3.5 Marco

 public string ReverseString(string srtVarable) { return new string(srtVarable.Reverse().ToArray()); } 

De acuerdo, con el interés de “no se repita”, ofrezco la siguiente solución:

 public string Reverse(string text) { return Microsoft.VisualBasic.Strings.StrReverse(text); } 

Según entiendo, esta implementación, disponible por defecto en VB.NET, maneja adecuadamente los caracteres Unicode.

Greg Beech publicó una opción unsafe que, de hecho, es lo más rápida posible (es una inversión in situ); pero, como indicó en su respuesta, es una idea completamente desastrosa .

Dicho esto, me sorprende que haya tanto consenso en que Array.Reverse es el método más rápido. Todavía hay un enfoque unsafe que devuelve una copia invertida de una cadena (sin Array.Reverse in situ) significativamente más rápido que el método Array.Reverse para cadenas pequeñas:

 public static unsafe string Reverse(string text) { int len = text.Length; // Why allocate a char[] array on the heap when you won't use it // outside of this method? Use the stack. char* reversed = stackalloc char[len]; // Avoid bounds-checking performance penalties. fixed (char* str = text) { int i = 0; int j = i + len - 1; while (i < len) { reversed[i++] = str[j--]; } } // Need to use this overload for the System.String constructor // as providing just the char* pointer could result in garbage // at the end of the string (no guarantee of null terminator). return new string(reversed, 0, len); } 

Aquí hay algunos resultados de referencia .

Puede ver que la ganancia de rendimiento se reduce y luego desaparece frente al método Array.Reverse medida que las cadenas Array.Reverse tamaño. Sin embargo, para cuerdas de tamaño pequeño a mediano, es difícil superar este método.

La respuesta fácil y agradable es usar el Método de extensión:

 static class ExtentionMethodCollection { public static string Inverse(this string @base) { return new string(@base.Reverse().ToArray()); } } 

y aquí está la salida:

 string Answer = "12345".Inverse(); // = "54321" 

Si quieres jugar un juego realmente peligroso, este es de lejos el modo más rápido que hay (alrededor de cuatro veces más rápido que el método Array.Reverse ). Es un reverso in situ utilizando punteros.

Tenga en cuenta que realmente no lo recomiendo para ningún uso, nunca ( eche un vistazo aquí por algunas razones por las que no debe usar este método ), pero es interesante ver que se puede hacer y que las cadenas no son realmente inmutables. una vez que enciendes el código no seguro.

 public static unsafe string Reverse(string text) { if (string.IsNullOrEmpty(text)) { return text; } fixed (char* pText = text) { char* pStart = pText; char* pEnd = pText + text.Length - 1; for (int i = text.Length / 2; i >= 0; i--) { char temp = *pStart; *pStart++ = *pEnd; *pEnd-- = temp; } return text; } } 

En primer lugar, no necesita llamar a ToCharArray ya que una cadena ya puede ser indexada como una matriz de caracteres, por lo que le ahorrará una asignación.

La próxima optimización es usar un StringBuilder para evitar asignaciones innecesarias (ya que las cadenas son inmutables, concatenándolas hace una copia de la cadena cada vez). Para optimizar aún más esto preestablecemos la longitud de StringBuilder para que no necesite expandir su búfer.

 public string Reverse(string text) { if (string.IsNullOrEmpty(text)) { return text; } StringBuilder builder = new StringBuilder(text.Length); for (int i = text.Length - 1; i >= 0; i--) { builder.Append(text[i]); } return builder.ToString(); } 

Editar: datos de rendimiento

Array.Reverse esta función y la función usando Array.Reverse con el siguiente progtwig simple, donde Reverse1 es una función y Reverse2 es la otra:

 static void Main(string[] args) { var text = "abcdefghijklmnopqrstuvwxyz"; // pre-jit text = Reverse1(text); text = Reverse2(text); // test var timer1 = Stopwatch.StartNew(); for (var i = 0; i < 10000000; i++) { text = Reverse1(text); } timer1.Stop(); Console.WriteLine("First: {0}", timer1.ElapsedMilliseconds); var timer2 = Stopwatch.StartNew(); for (var i = 0; i < 10000000; i++) { text = Reverse2(text); } timer2.Stop(); Console.WriteLine("Second: {0}", timer2.ElapsedMilliseconds); Console.ReadLine(); } 

Resulta que para cadenas cortas, el método Array.Reverse es dos veces más rápido que el anterior, y para cadenas más largas la diferencia es aún más pronunciada. Array.Reverse que el método Array.Reverse es tanto más simple como más rápido, te recomendaría que lo uses en lugar de este. Dejo este aquí solo para mostrar que no es la forma en que debes hacerlo (¡para mi sorpresa!)

Eche un vistazo a la entrada de wikipedia aquí . Implementan el método de extensión String.Reverse. Esto le permite escribir un código como este:

 string s = "olleh"; s.Reverse(); 

También usan la combinación ToCharArray / Reverse que sugieren otras respuestas a esta pregunta. El código fuente se ve así:

 public static string Reverse(this string input) { char[] chars = input.ToCharArray(); Array.Reverse(chars); return new String(chars); } 

Intenta usar Array.Reverse

 public string Reverse(string str) { char[] array = str.ToCharArray(); Array.Reverse(array); return new string(array); } 
 public static string Reverse(string input) { return string.Concat(Enumerable.Reverse(input)); } 

Por supuesto, puede ampliar la clase de cuerda con el método inverso

 public static class StringExtensions { public static string Reverse(this string input) { return string.Concat(Enumerable.Reverse(input)); } } 

No te molestes con una función, solo hazlo en su lugar. Nota: La segunda línea generará una excepción de argumento en la ventana Inmediato de algunas versiones de VS.

 string s = "Blah"; s = new string(s.ToCharArray().Reverse().ToArray()); 

Tuve que enviar un ejemplo recursivo:

 private static string Reverse(string str) { if (str.IsNullOrEmpty(str) || str.Length == 1) return str; else return str[str.Length - 1] + Reverse(str.Substring(0, str.Length - 1)); } 

Lo siento por la publicación larga, pero esto podría ser interesante

 using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace ConsoleApplication1 { class Program { public static string ReverseUsingArrayClass(string text) { char[] chars = text.ToCharArray(); Array.Reverse(chars); return new string(chars); } public static string ReverseUsingCharacterBuffer(string text) { char[] charArray = new char[text.Length]; int inputStrLength = text.Length - 1; for (int idx = 0; idx <= inputStrLength; idx++) { charArray[idx] = text[inputStrLength - idx]; } return new string(charArray); } public static string ReverseUsingStringBuilder(string text) { if (string.IsNullOrEmpty(text)) { return text; } StringBuilder builder = new StringBuilder(text.Length); for (int i = text.Length - 1; i >= 0; i--) { builder.Append(text[i]); } return builder.ToString(); } private static string ReverseUsingStack(string input) { Stack resultStack = new Stack(); foreach (char c in input) { resultStack.Push(c); } StringBuilder sb = new StringBuilder(); while (resultStack.Count > 0) { sb.Append(resultStack.Pop()); } return sb.ToString(); } public static string ReverseUsingXOR(string text) { char[] charArray = text.ToCharArray(); int length = text.Length - 1; for (int i = 0; i < length; i++, length--) { charArray[i] ^= charArray[length]; charArray[length] ^= charArray[i]; charArray[i] ^= charArray[length]; } return new string(charArray); } static void Main(string[] args) { string testString = string.Join(";", new string[] { new string('a', 100), new string('b', 101), new string('c', 102), new string('d', 103), }); int cycleCount = 100000; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < cycleCount; i++) { ReverseUsingCharacterBuffer(testString); } stopwatch.Stop(); Console.WriteLine("ReverseUsingCharacterBuffer: " + stopwatch.ElapsedMilliseconds + "ms"); stopwatch.Reset(); stopwatch.Start(); for (int i = 0; i < cycleCount; i++) { ReverseUsingArrayClass(testString); } stopwatch.Stop(); Console.WriteLine("ReverseUsingArrayClass: " + stopwatch.ElapsedMilliseconds + "ms"); stopwatch.Reset(); stopwatch.Start(); for (int i = 0; i < cycleCount; i++) { ReverseUsingStringBuilder(testString); } stopwatch.Stop(); Console.WriteLine("ReverseUsingStringBuilder: " + stopwatch.ElapsedMilliseconds + "ms"); stopwatch.Reset(); stopwatch.Start(); for (int i = 0; i < cycleCount; i++) { ReverseUsingStack(testString); } stopwatch.Stop(); Console.WriteLine("ReverseUsingStack: " + stopwatch.ElapsedMilliseconds + "ms"); stopwatch.Reset(); stopwatch.Start(); for (int i = 0; i < cycleCount; i++) { ReverseUsingXOR(testString); } stopwatch.Stop(); Console.WriteLine("ReverseUsingXOR: " + stopwatch.ElapsedMilliseconds + "ms"); } } } 

Resultados:

  • ReverseUsingCharacterBuffer: 346ms
  • ReverseUsingArrayClass: 87 ms
  • ReverseUsingStringBuilder: 824ms
  • ReverseUsingStack: 2086ms
  • ReverseUsingXOR: 319ms

Solución basada en stack.

  public static string Reverse(string text) { var stack = new Stack(text); var array = new char[stack.Count]; int i = 0; while (stack.Count != 0) { array[i++] = stack.Pop(); } return new string(array); } 

O

  public static string Reverse(string text) { var stack = new Stack(text); return string.Join("", stack); } 

Qué tal si:

  private string Reverse(string stringToReverse) { char[] rev = stringToReverse.Reverse().ToArray(); return new string(rev); } 
 public string Reverse(string input) { char[] output = new char[input.Length]; int forwards = 0; int backwards = input.Length - 1; do { output[forwards] = input[backwards]; output[backwards] = input[forwards]; }while(++forwards <= --backwards); return new String(output); } public string DotNetReverse(string input) { char[] toReverse = input.ToCharArray(); Array.Reverse(toReverse); return new String(toReverse); } public string NaiveReverse(string input) { char[] outputArray = new char[input.Length]; for (int i = 0; i < input.Length; i++) { outputArray[i] = input[input.Length - 1 - i]; } return new String(outputArray); } public string RecursiveReverse(string input) { return RecursiveReverseHelper(input, 0, input.Length - 1); } public string RecursiveReverseHelper(string input, int startIndex , int endIndex) { if (startIndex == endIndex) { return "" + input[startIndex]; } if (endIndex - startIndex == 1) { return "" + input[endIndex] + input[startIndex]; } return input[endIndex] + RecursiveReverseHelper(input, startIndex + 1, endIndex - 1) + input[startIndex]; } void Main() { int[] sizes = new int[] { 10, 100, 1000, 10000 }; for(int sizeIndex = 0; sizeIndex < sizes.Length; sizeIndex++) { string holaMundo = ""; for(int i = 0; i < sizes[sizeIndex]; i+= 5) { holaMundo += "ABCDE"; } string.Format("\n**** For size: {0} ****\n", sizes[sizeIndex]).Dump(); string odnuMaloh = DotNetReverse(holaMundo); var stopWatch = Stopwatch.StartNew(); string result = NaiveReverse(holaMundo); ("Naive Ticks: " + stopWatch.ElapsedTicks).Dump(); stopWatch.Restart(); result = Reverse(holaMundo); ("Efficient linear Ticks: " + stopWatch.ElapsedTicks).Dump(); stopWatch.Restart(); result = RecursiveReverse(holaMundo); ("Recursive Ticks: " + stopWatch.ElapsedTicks).Dump(); stopWatch.Restart(); result = DotNetReverse(holaMundo); ("DotNet Reverse Ticks: " + stopWatch.ElapsedTicks).Dump(); } } 

Salida

Para el tamaño: 10

 Naive Ticks: 1 Efficient linear Ticks: 0 Recursive Ticks: 2 DotNet Reverse Ticks: 1 

Para el tamaño: 100

 Naive Ticks: 2 Efficient linear Ticks: 1 Recursive Ticks: 12 DotNet Reverse Ticks: 1 

Para el tamaño: 1000

 Naive Ticks: 5 Efficient linear Ticks: 2 Recursive Ticks: 358 DotNet Reverse Ticks: 9 

Para el tamaño: 10000

 Naive Ticks: 32 Efficient linear Ticks: 28 Recursive Ticks: 84808 DotNet Reverse Ticks: 33 

He creado un puerto C # de Microsoft.VisualBasic.Strings . No estoy seguro de por qué conservan funciones tan útiles (desde VB) fuera de System.String en Framework, pero aún bajo Microsoft.VisualBasic. El mismo escenario para las funciones financieras (por ejemplo, Microsoft.VisualBasic.Financial.Pmt() ).

 public static string StrReverse(this string expression) { if ((expression == null)) return ""; int srcIndex; var length = expression.Length; if (length == 0) return ""; //CONSIDER: Get System.String to add a surrogate aware Reverse method //Detect if there are any graphemes that need special handling for (srcIndex = 0; srcIndex <= length - 1; srcIndex++) { var ch = expression[srcIndex]; var uc = char.GetUnicodeCategory(ch); if (uc == UnicodeCategory.Surrogate || uc == UnicodeCategory.NonSpacingMark || uc == UnicodeCategory.SpacingCombiningMark || uc == UnicodeCategory.EnclosingMark) { //Need to use special handling return InternalStrReverse(expression, srcIndex, length); } } var chars = expression.ToCharArray(); Array.Reverse(chars); return new string(chars); } ///This routine handles reversing Strings containing graphemes /// GRAPHEME: a text element that is displayed as a single character private static string InternalStrReverse(string expression, int srcIndex, int length) { //This code can only be hit one time var sb = new StringBuilder(length) { Length = length }; var textEnum = StringInfo.GetTextElementEnumerator(expression, srcIndex); //Init enumerator position if (!textEnum.MoveNext()) { return ""; } var lastSrcIndex = 0; var destIndex = length - 1; //Copy up the first surrogate found while (lastSrcIndex < srcIndex) { sb[destIndex] = expression[lastSrcIndex]; destIndex -= 1; lastSrcIndex += 1; } //Now iterate through the text elements and copy them to the reversed string var nextSrcIndex = textEnum.ElementIndex; while (destIndex >= 0) { srcIndex = nextSrcIndex; //Move to next element nextSrcIndex = (textEnum.MoveNext()) ? textEnum.ElementIndex : length; lastSrcIndex = nextSrcIndex - 1; while (lastSrcIndex >= srcIndex) { sb[destIndex] = expression[lastSrcIndex]; destIndex -= 1; lastSrcIndex -= 1; } } return sb.ToString(); } 

“Best” can depend on many things, but here are few more short alternatives ordered from fast to slow:

 string s = "z̽a̎l͘g̈o̓😀😆", pattern = @"(?s).(?<=(?:.(?=.*$(?<=((\P{M}\p{C}?\p{M}*)\1?))))*)"; string s1 = string.Concat(s.Reverse()); // "☐😀☐̓ög͘l̎a̽z" 👎 string s2 = Microsoft.VisualBasic.Strings.StrReverse(s); // "😆😀o̓g̈l͘a̎̽z" 👌 string s3 = string.Concat(StringInfo.ParseCombiningCharacters(s).Reverse() .Select(i => StringInfo.GetNextTextElement(s, i))); // "😆😀o̓g̈l͘a̎z̽" 👍 string s4 = Regex.Replace(s, pattern, "$2").Remove(s.Length); // "😆😀o̓g̈l͘a̎z̽" 👍 

“Better way” depends on what is more important to you in your situation, performance, elegance, maintainability etc.

Anyway, here’s an approach using Array.Reverse:

 string inputString="The quick brown fox jumps over the lazy dog."; char[] charArray = inputString.ToCharArray(); Array.Reverse(charArray); string reversed = new string(charArray); 

If you have a string that only contains ASCII characters, you can use this method.

  public static string ASCIIReverse(string s) { byte[] reversed = new byte[s.Length]; int k = 0; for (int i = s.Length - 1; i >= 0; i--) { reversed[k++] = (byte)s[i]; } return Encoding.ASCII.GetString(reversed); } 

Sorry for posting on this old thread. I am practicing some code for an interview.

This was what I came up with for C#. My first version before refactoring was horrible.

 static String Reverse2(string str) { int strLen = str.Length, elem = strLen - 1; char[] charA = new char[strLen]; for (int i = 0; i < strLen; i++) { charA[elem] = str[i]; elem--; } return new String(charA); } 

In Contrast to the Array.Reverse method below, it appears faster with 12 characters or less in the string. After 13 characters, the Array.Reverse starts to get faster, and it eventually dominates pretty heavily on speed. I just wanted to point out approximately where the speed starts to change.

 static String Reverse(string str) { char[] charA = str.ToCharArray(); Array.Reverse(charA); return new String(charA); } 

At 100 characters in the string, it is faster than my version x 4. However, if I knew that the strings would always be less than 13 characters, I would use the one I made.

Testing was done with Stopwatch and 5000000 iterations. Also, I'm not sure if my version handles Surrogates or combined character situations with Unicode encoding.

 public static string reverse(string s) { string r = ""; for (int i = s.Length; i > 0; i--) r += s[i - 1]; return r; } 

As simple as this:

 string x = "your string"; string x1 = ""; for(int i = x.Length-1 ; i >= 0; i--) x1 += x[i]; Console.WriteLine("The reverse of the string is:\n {0}", x1); 

See the output .

How about use Substring

 static string ReverseString(string text) { string sub = ""; int indexCount = text.Length - 1; for (int i = indexCount; i > -1; i--) { sub = sub + text.Substring(i, 1); } return sub; } 

If it ever came up in an interview and you were told you can’t use Array.Reverse, i think this might be one of the fastest. It does not create new strings and iterates only over half of the array (ie O(n/2) iterations)

  public static string ReverseString(string stringToReverse) { char[] charArray = stringToReverse.ToCharArray(); int len = charArray.Length-1; int mid = len / 2; for (int i = 0; i < mid; i++) { char tmp = charArray[i]; charArray[i] = charArray[len - i]; charArray[len - i] = tmp; } return new string(charArray); } 
 public static string Reverse2(string x) { char[] charArray = new char[x.Length]; int len = x.Length - 1; for (int i = 0; i <= len; i++) charArray[i] = x[len - i]; return new string(charArray); } 
 private static string Reverse(string str) { string revStr = string.Empty; for (int i = str.Length - 1; i >= 0; i--) { revStr += str[i].ToString(); } return revStr; } 

Faster than above method

 private static string ReverseEx(string str) { char[] chrArray = str.ToCharArray(); int len = chrArray.Length - 1; char rev = 'n'; for (int i = 0; i <= len/2; i++) { rev = chrArray[i]; chrArray[i] = chrArray[len - i]; chrArray[len - i] = rev; } return new string(chrArray); }