c# - numero - invertir una cadena en visual basic
La mejor manera de revertir una cadena (30)
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í?
Aquí una solución que invierte correctamente la cadena "Les Mise/u0301rables"
como "selbare/u0301siM seL"
. Esto debería selbarésiM seL
como selbarésiM seL
, no selbaŕesiM seL
(observe la posición del acento), como lo harí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 (reversa con especial cuidado para pares sustitutos) ).
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
public static class Test
{
private static IEnumerable<string> 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 ejemplo de ejecución en vivo aquí: https://ideone.com/DqAeMJ )
Simplemente utiliza la API .NET para la iteración del clúster de grafema , que ha estado allí desde siempre, pero parece un poco "oculto" a la vista.
Desde arriba del Marco 3.5
public string ReverseString(string srtVarable)
{
return new string(srtVarable.Reverse().ToArray());
}
Echa un vistazo a la entrada de wikipedia here . Implementan el método de extensión String.Reverse. Esto te permite escribir 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);
}
En primer lugar, no necesita llamar a ToCharArray
ya que una cadena ya se puede indexar como una matriz de caracteres, por lo que le ahorrará una asignación.
La próxima optimización es utilizar un StringBuilder
para evitar asignaciones innecesarias (ya que las cadenas son inmutables, concatenarlas hace una copia de la cadena cada vez). Para optimizar aún más esto, preestablecemos la longitud del 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();
}
Edición: Datos de rendimiento
Array.Reverse
esta función y la función usando Array.Reverse
con el siguiente programa 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 aproximadamente dos veces más rápido que el de arriba, y para cadenas más largas, la diferencia es aún más pronunciada. Entonces, dado que el método Array.Reverse
es más simple y más rápido, te recomiendo que uses eso en lugar de este. Lo dejo aquí solo para demostrar que no es la forma en que deberías hacerlo (¡para mi sorpresa!)
Esto se está convirtiendo en una pregunta sorprendentemente difícil.
Recomendaría usar Array.Reverse para la mayoría de los casos, ya que está codificado de forma nativa y es muy simple de mantener y entender.
Parece que supera 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 utiliza 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 conjunto completo de caracteres Unicode UTF16, lea esto . Y usa la implementación allí en su lugar. Puede optimizarse aún más usando uno de los algoritmos anteriores y ejecutando la cadena para limpiarlo después de que se invierten los caracteres.
Aquí hay una comparación de rendimiento entre los métodos 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.
Greg Beech publicó una opción unsafe
que es de hecho tan rápida como es posible (es una reversión en el lugar); pero, como indicó en su respuesta, es una idea completamente desastrosa .
Dicho esto, me sorprende que haya tanto consenso 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 cambios de Array.Reverse
en el lugar) 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 contra el método Array.Reverse
medida que las cadenas se hacen más grandes. Sin embargo, para cuerdas de tamaño pequeño a mediano, es difícil superar este método.
He hecho un puerto C # de Microsoft.VisualBasic.Strings . No estoy seguro de por qué mantienen esas funciones útiles (de VB) fuera de System.String en Framework, pero aún bajo Microsoft.VisualBasic. Mismo escenario para 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);
}
///<remarks>This routine handles reversing Strings containing graphemes
/// GRAPHEME: a text element that is displayed as a single character</remarks>
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();
}
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"
Lo siento por el post largo, 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<char> resultStack = new Stack<char>();
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: 87ms
- ReverseUsingStringBuilder: 824ms
- ReverseUsingStack: 2086ms
- ReverseUsingXOR: 319ms
No te molestes con una función, solo hazlo en su lugar. Nota: La segunda línea lanzará una excepción de argumento en la ventana Inmediato de algunas versiones de VS.
string s = "Blah";
s = new string(s.ToCharArray().Reverse().ToArray());
Ok, en el interés de "no se repita", ofrezco la siguiente solución:
public string Reverse(string text)
{
return Microsoft.VisualBasic.Strings.StrReverse(text);
}
Mi entendimiento es que esta implementación, disponible de forma predeterminada en VB.NET, maneja adecuadamente los caracteres Unicode.
Qué tal si:
private string Reverse(string stringToReverse)
{
char[] rev = stringToReverse.Reverse().ToArray();
return new string(rev);
}
Si la cadena contiene datos Unicode (en sentido estricto, caracteres que no son BMP), los otros métodos que se han publicado los corromperán, porque no puede intercambiar el orden de las unidades de código sustituto alto y bajo al invertir la cadena. (Puede encontrar más información sobre esto en mi blog ).
El siguiente ejemplo de código revertirá correctamente una cadena que contiene caracteres que no son BMP, por ejemplo, "/ U00010380 / U00010381" (Ugaritic Letter Alpa, Ugaritic Letter 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);
}
Si quieres jugar un juego realmente peligroso, esta es la forma más rápida que existe (alrededor de cuatro veces más rápido que el método Array.Reverse
). Es un reverso en el lugar utilizando punteros.
Tenga en cuenta que realmente no lo recomiendo para ningún uso ( vea algunas razones por las que no debería usar este método ), pero es interesante ver que se puede hacer y que las cadenas no son realmente inmutables. Una vez que encienda el código inseguro.
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;
}
}
Solución basada en la pila.
public static string Reverse(string text)
{
var stack = new Stack<char>(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<char>(text);
return string.Join("", stack);
}
Trate de usar Array.Reverse
public string Reverse(string str)
{
char[] array = str.ToCharArray();
Array.Reverse(array);
return new string(array);
}
Tuvo que presentar 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 mejor" puede depender de muchas cosas, pero aquí hay algunas alternativas más cortas ordenadas de rápido a lento:
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̽" 👍
¿Qué hay de usar subcadena
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;
}
La "mejor manera" depende de lo que sea más importante para usted en su situación, rendimiento, elegancia, capacidad de mantenimiento, etc.
De todos modos, aquí hay un enfoque utilizando 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);
Si tiene una cadena que solo contiene caracteres ASCII, puede usar este método.
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);
}
Tan simple como esto:
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);
Ver la output .
Lo siento por publicar en este viejo hilo. Estoy practicando un código para una entrevista.
Esto fue lo que se me ocurrió para C #. Mi primera versión antes de refactorizar fue 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);
}
En contraste con el Array.Reverse
método a continuación, aparece más rápido con 12 caracteres o menos en la cadena. Después de 13 caracteres, el Array.Reverse
comienzo se vuelve más rápido y eventualmente domina bastante en la velocidad. Solo quería señalar aproximadamente donde la velocidad comienza a cambiar.
static String Reverse(string str)
{
char[] charA = str.ToCharArray();
Array.Reverse(charA);
return new String(charA);
}
Con 100 caracteres en la cadena, es más rápido que mi versión x 4. Sin embargo, si supiera que las cadenas siempre tendrían menos de 13 caracteres, usaría el que hice.
Las pruebas se realizaron con Stopwatch
y 5000000 iteraciones. Además, no estoy seguro de si mi versión maneja sustitutos o situaciones de caracteres combinados con Unicode
codificación.
Si alguna vez surgió en una entrevista y le dijeron que no puede usar Array. Al revés, creo que este podría ser uno de los más rápidos. No crea nuevas cadenas e itera solo más de la mitad de la matriz (es decir, iteraciones O (n / 2))
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);
}
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;
}
Más rápido que el método anterior
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);
}
public static string Reverse( string s )
{
char[] charArray = s.ToCharArray();
Array.Reverse( charArray );
return new string( charArray );
}
public static string Reverse(string input)
{
return string.Concat(Enumerable.Reverse(input));
}
Por supuesto que puede extender la clase de cadena con el método inverso
public static class StringExtensions
{
public static string Reverse(this string input)
{
return string.Concat(Enumerable.Reverse(input));
}
}
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);
}
public static string reverse(string s)
{
string r = "";
for (int i = s.Length; i > 0; i--) r += s[i - 1];
return r;
}
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
Por talla: 10
Naive Ticks: 1
Efficient linear Ticks: 0
Recursive Ticks: 2
DotNet Reverse Ticks: 1
Por 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