A melhor maneira de reverter um texto

acabei de escrever uma função inversa de cadeia de caracteres em C # 2.0 (isto é, LINQ não disponível) e surgiu com isto:

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;
}
Pessoalmente, não gosto muito da função e estou convencido de que há uma maneira melhor de o fazer. Há?

Author: R. Martinho Fernandes, 2008-10-23

30 answers

public static string Reverse( string s )
{
    char[] charArray = s.ToCharArray();
    Array.Reverse( charArray );
    return new string( charArray );
}
 462
Author: PeteT, 2017-11-04 19:32:19

Aqui uma solução que inverte adequadamente a cadeia "Les Mise\u0301rables" como "selbare\u0301siM seL". Isso deve render apenas como selbarésiM seL não selbaŕesiM seL (note a posição do acento), como seria o resultado da maioria das implementações com base em unidades de código (Array.Reverse, etc) ou mesmo pontos de código (invertendo com cuidado especial para pares de substituição).

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);
    }
}

(e viva o exemplo de execução aqui: https://ideone.com/DqAeMJ)

Ele simplesmente usa a API. net para a iteração do aglomerado de grapheme, que foi desde sempre, mas um pouco" escondido " da vista, parece.

 143
Author: R. Martinho Fernandes, 2013-07-24 16:19:10
Esta é uma pergunta surpreendentemente complicada. Eu recomendaria usar o Array.Reverter para a maioria dos casos como é codificado nativamente e é muito simples de manter e entender. Parece ter um desempenho superior ao do Construtor de cordas em todos os casos que testei.
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);
}

Existe uma segunda abordagem que pode ser mais rápida para certos comprimentos de cadeia 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 se quiser suportar a codificação Unicode UTF16 completa lê isto . E use a implementação lá em vez disso. Ele pode ser otimizado ainda mais usando um dos algoritmos acima e executando através da cadeia de caracteres para limpá-lo depois que os caracteres são invertidos.

Aqui está uma comparação de desempenho entre o StringBuilder, Array.Método inverso e 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();
        }
    }
}

Aqui estão os 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 o Xor pode ser mais rápido para cordas curtas.
 119
Author: Sam Saffron, 2017-05-23 12:34:51

Se a cadeia de caracteres contém dados Unicode (estritamente falando, caracteres não-BMP), os outros métodos que foram publicados Irão corrompê-lo, porque você não pode trocar a ordem de unidades de código substitutas altas e baixas ao inverter a cadeia de caracteres. (Mais informações sobre isso podem ser encontradas em Meu blog .)

A seguinte amostra de código irá reverter correctamente uma cadeia que contém caracteres não-BMP, por exemplo, "\U00010380\U00010381" (letra Ugarítica Alpa, letra 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);
}
 47
Author: Bradley Grainger, 2008-10-23 04:08:22

A partir do ponto 3.5

public string ReverseString(string srtVarable)
{
    return new string(srtVarable.Reverse().ToArray());
}
 39
Author: SGRao, 2016-04-14 08:51:21

Ok, no interesse de "não se repita", eu ofereço a seguinte solução:

public string Reverse(string text)
{
   return Microsoft.VisualBasic.Strings.StrReverse(text);
}
O meu entendimento é que esta implementação, disponível por defeito em VB.NET, lida adequadamente com caracteres Unicode.
 23
Author: richardtallent, 2011-12-07 17:06:20
Greg Beech postou uma opção que é o mais rápido possível (é uma inversão no lugar), mas, como ele indicou em sua resposta, é uma ideia completamente desastrosa. Dito isto, surpreende-me que haja tanto consenso que Array.Reverse é o método mais rápido. Ainda existe uma abordagem unsafe que devolve uma cópia invertida de uma string (sem shenanigans de reversão no local) significativamente mais rápida do que o método Array.Reverse para os pequenos cordas:
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);
}

Aqui estão alguns resultados de Referência.

Você pode ver que o ganho de desempenho encolhe e, em seguida, desaparece contra o método {[[2]} à medida que as cordas ficam maiores. Para cordas de pequeno a médio porte, no entanto, é difícil vencer este método.

 17
Author: Dan Tao, 2013-04-30 00:19:44

A resposta fácil e agradável é usar o método de extensão:

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

E aqui está a saída:

string Answer = "12345".Inverse(); // = "54321"
 13
Author: Mehdi Khademloo, 2016-07-18 00:06:57

Se você quer jogar um jogo realmente perigoso, então esta é de longe a maneira mais rápida que existe (cerca de quatro vezes mais rápido do que o método Array.Reverse). É um reverso no lugar usando ponteiros.

Note que eu realmente não recomendo isso para qualquer uso, nunca (dê uma olhada aqui por algumas razões porque você não deve usar este método), mas é apenas interessante ver que ele pode ser feito, e que as cordas não são realmente imutáveis uma vez que você liga 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;
    }
}
 12
Author: Greg Beech, 2017-05-23 12:34:51

Dê uma olhada na entrada na Wikipédia aqui . Eles implementam a corda.Método de extensão inversa. Isto permite-lhe escrever um código como este:

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

Eles também usam a combinação Tocharray / reversa que outras respostas a esta pergunta sugerem. O código-fonte é o seguinte:

public static string Reverse(this string input)
{
    char[] chars = input.ToCharArray();
    Array.Reverse(chars);
    return new String(chars);
}
 11
Author: Mike Thompson, 2008-10-23 00:58:56

Em Primeiro Lugar, você não precisa chamar {[[2]} como uma string já pode ser indexada como um array de char, então isso irá poupar-lhe uma alocação.

A próxima optimização é usar um StringBuilder para evitar atribuições desnecessárias (uma vez que as cadeias de caracteres são imutáveis, concatenando-as faz uma cópia da cadeia de caracteres cada vez). Para otimizar ainda mais isso, pré-definimos o comprimento do StringBuilder para que ele não precise expandir seu buffer.

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: Dados De Desempenho

Eu testei isto. função e função usando Array.Reverse com o seguinte programa simples, em que Reverse1 é uma função e Reverse2 é a outra:
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();
}

Acontece que para cadeias curtas o método Array.Reverse é duas vezes mais rápido do que o acima, e para cadeias mais longas a diferença é ainda mais pronunciada. Então, dado que o método Array.Reverse é ao mesmo tempo mais simples e rápido, eu recomendo que você use isso em vez deste. Eu deixo este aqui em cima só para mostrar que não é a maneira que você deve fazê-lo (muito para a minha surpresa!)

 11
Author: Greg Beech, 2008-10-23 01:12:33

Tente usar o Array.Marcha-atrás


public string Reverse(string str)
{
    char[] array = str.ToCharArray();
    Array.Reverse(array);
    return new string(array);
}
 9
Author: Mike Two, 2008-10-23 00:48:33
public static string Reverse(string input)
{
    return string.Concat(Enumerable.Reverse(input));
}

Claro que pode estender a classe de texto com o método inverso

public static class StringExtensions
{
    public static string Reverse(this string input)
    {
        return string.Concat(Enumerable.Reverse(input));
    }
}
 9
Author: Vlad Bezden, 2013-04-09 17:47:44
Não te incomodes com uma função, fá-lo no lugar. Nota:a segunda linha irá lançar uma exceção de argumento na janela imediata de algumas versões VS.
string s = "Blah";
s = new string(s.ToCharArray().Reverse().ToArray()); 
 6
Author: B H, 2013-04-02 00:45:52

Teve de submeter um exemplo 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));
}
 5
Author: JPrescottSanders, 2015-05-06 10:46:36

Desculpa pelo longo post, mas isto pode ser interessante

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
  • Construtor ReverseUsingStringBuilder: 824ms
  • ReverseUsingStack: 2086ms
  • ReverseUsingXOR: 319ms
 4
Author: aku, 2008-10-23 01:17:58

Solução baseada em pilha.

    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);
    }

Ou

    public static string Reverse(string text)
    {
        var stack = new Stack<char>(text);
        return string.Join("", stack);
    }
 4
Author: Raz Megrelidze, 2014-06-17 22:35:30

Que tal:

    private string Reverse(string stringToReverse)
    {
        char[] rev = stringToReverse.Reverse().ToArray();
        return new string(rev); 
    }
 3
Author: Zamir, 2011-02-04 01:03:52
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();
    }
}

Resultado

Para o tamanho: 10

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

Para o tamanho: 100

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

Para o tamanho: 1000

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

Para o tamanho: 10000

Naive Ticks: 32
Efficient linear Ticks: 28
Recursive Ticks: 84808
DotNet Reverse Ticks: 33
 3
Author: Marcel Valdez Orozco, 2013-05-15 15:52:34

Fiz uma porta C# da Microsoft.VisualBasic.Cordas . Não tenho certeza por que eles mantêm funções tão úteis (de VB) fora do sistema.String in Framework, but still under Microsoft.VisualBasic. O mesmo cenário para as funções financeiras (por exemplo 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();
}
 3
Author: natenho, 2014-06-30 21:31:58

O"melhor" pode depender de muitas coisas, mas aqui estão algumas alternativas mais curtas 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̽"  
 3
Author: Slai, 2017-10-01 18:38:32

"melhor maneira" depende do que é mais importante para si na sua situação, desempenho, elegância, manutenção, etc.

De qualquer forma, aqui está uma abordagem usando Array.Marcha-atrás:
string inputString="The quick brown fox jumps over the lazy dog.";
char[] charArray = inputString.ToCharArray(); 
Array.Reverse(charArray); 

string reversed = new string(charArray);
 2
Author: Ash, 2008-10-23 00:41:32

Se tiver um texto que contenha apenas caracteres ASCII, pode 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);
    }
 2
Author: Raz Megrelidze, 2014-01-29 12:19:52
Desculpa por postares neste velho tópico. Estou a praticar um código para uma entrevista. Isto foi o que eu inventei para C#. A minha primeira versão antes do refactoring foi horrível.
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);
}

Em contraste com o método Array.Reverse abaixo, aparece mais rápido com 12 caracteres ou menos na cadeia de caracteres. Depois de 13 personagens, o Array.Reverse começa a ficar mais rápido, e eventualmente domina bastante a velocidade. Eu só queria apontar aproximadamente onde a velocidade começa a alterar.

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

    Array.Reverse(charA);

    return new String(charA);
}

A 100 caracteres no texto, é mais rápido do que a minha versão x 4. No entanto, se eu soubesse que as cordas seriam sempre menos de 13 caracteres, eu usaria o que eu fiz.

Os testes foram feitos com Stopwatch e 5000000 iterações. Além disso, Não tenho a certeza se a minha versão lida com substitutos ou situações combinadas de caracteres com codificação Unicode.

 2
Author: Jason Ausborn, 2015-06-19 11:13:04
public static string reverse(string s) 
{
    string r = "";
    for (int i = s.Length; i > 0; i--) r += s[i - 1];
    return r;
}
 2
Author: ddagsan, 2015-10-29 11:58:58

Tão simples como isto:

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 a saída.

 2
Author: Raktim Biswas, 2016-09-21 17:05:35

Que tal usar 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;
}
 2
Author: joegreentea, 2018-02-14 20:39:09
Se alguma vez apareceu numa entrevista e te disseram que não podes usar o Array.Ao contrário, acho que este pode ser um dos mais rápidos. Ele não cria novas cadeias de caracteres e itera apenas mais de metade da matriz (I. E. O(N/2) iterações)
    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);
    }
 1
Author: mike01010, 2012-02-16 07:21:35
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);
        }
 1
Author: Shrini, 2012-04-27 07:46:46
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;
        }

Mais rápido do que o método acima

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);
        }
 1
Author: vikas, 2013-02-22 02:09:48