我刚刚在c# 2.0中写了一个字符串反向函数(即LINQ不可用),然后想到了这个:

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

就我个人而言,我并不喜欢这个功能,我相信有更好的方法来实现它。是吗?


当前回答

好吧,为了“不要重复你自己”,我提供以下解决方案:

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

我的理解是这个实现,在VB中默认可用。NET,正确地处理Unicode字符。

其他回答

    string original = "Stack Overflow";
    string reversed = new string(original.Reverse().ToArray());

从。net Core 2.1开始,有一种新的方法可以使用字符串反转字符串。创建方法。

请注意,这个解决方案不能正确处理Unicode组合字符等,因为“Les Mise\u0301rables”将被转换为“selbarésiM seL”。请参阅其他答案以获得更好的解决方案。

public static string Reverse(string input)
{
    return string.Create<string>(input.Length, input, (chars, state) =>
    {
        state.AsSpan().CopyTo(chars);
        chars.Reverse();
    });
}

这实际上是将输入的字符复制到一个新字符串,并在适当的位置反转新字符串。

为什么是弦。创建有用吗?

当从现有数组创建字符串时,将分配一个新的内部数组并复制其值。否则,就有可能在创建字符串之后(在安全的环境中)对其进行变异。也就是说,在下面的代码片段中,我们必须分配一个长度为10的数组两次,一次作为缓冲区,一次作为字符串的内部数组。

var chars = new char[10];
// set array values
var str = new string(chars);

字符串。Create本质上允许我们在字符串创建期间操作内部数组。也就是说,我们不再需要缓冲区,因此可以避免分配一个字符数组。

史蒂夫·戈登在这里写了更详细的内容。在MSDN上也有一篇文章。

如何使用string.Create?

public static string Create<TState>(int length, TState state, SpanAction<char, TState> action);

该方法有三个参数:

要创建的字符串长度, 你想用来动态创建新字符串的数据, 以及从数据创建最终字符串的委托,其中第一个参数指向新字符串的内部char数组,第二个参数是传递给string. create的数据(状态)。

在委托内部,我们可以指定如何从数据中创建新字符串。在本例中,我们只是将输入字符串的字符复制到新字符串使用的Span。然后我们反转Span,因此整个字符串都反转了。

基准

为了比较我提出的反转字符串的方法与已接受的答案,我使用BenchmarkDotNet编写了两个基准测试。

public class StringExtensions
{
    public static string ReverseWithArray(string input)
    {
        var charArray = input.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    public static string ReverseWithStringCreate(string input)
    {
        return string.Create(input.Length, input, (chars, state) =>
        {
            state.AsSpan().CopyTo(chars);
            chars.Reverse();
        });
    }
}

[MemoryDiagnoser]
public class StringReverseBenchmarks
{
    private string input;

    [Params(10, 100, 1000)]
    public int InputLength { get; set; }


    [GlobalSetup]
    public void SetInput()
    {
        // Creates a random string of the given length
        this.input = RandomStringGenerator.GetString(InputLength);
    }

    [Benchmark(Baseline = true)]
    public string WithReverseArray() => StringExtensions.ReverseWithArray(input);

    [Benchmark]
    public string WithStringCreate() => StringExtensions.ReverseWithStringCreate(input);
}

下面是我的测试结果:

| Method           | InputLength |         Mean |      Error |    StdDev |  Gen 0 | Allocated |
| ---------------- | ----------- | -----------: | ---------: | --------: | -----: | --------: |
| WithReverseArray | 10          |    45.464 ns |  0.4836 ns | 0.4524 ns | 0.0610 |      96 B |
| WithStringCreate | 10          |    39.749 ns |  0.3206 ns | 0.2842 ns | 0.0305 |      48 B |
|                  |             |              |            |           |        |           |
| WithReverseArray | 100         |   175.162 ns |  2.8766 ns | 2.2458 ns | 0.2897 |     456 B |
| WithStringCreate | 100         |   125.284 ns |  2.4657 ns | 2.0590 ns | 0.1473 |     232 B |
|                  |             |              |            |           |        |           |
| WithReverseArray | 1000        | 1,523.544 ns |  9.8808 ns | 8.7591 ns | 2.5768 |    4056 B |
| WithStringCreate | 1000        | 1,078.957 ns | 10.2948 ns | 9.6298 ns | 1.2894 |    2032 B |

正如你所看到的,使用ReverseWithStringCreate,我们只分配了ReverseWithArray方法使用的一半内存。

如果有人问关于字符串反向的问题,其目的可能是想知道你是否知道任何位操作,比如异或。c#中有数组。反向函数,但是,您可以使用简单的异或操作在几行代码(最少)

    public static string MyReverse(string s)
    {
        char[] charArray = s.ToCharArray();
        int bgn = -1;
        int end = s.Length;
        while(++bgn < --end)
        {
            charArray[bgn] ^= charArray[end];
            charArray[end] ^= charArray[bgn];
            charArray[bgn] ^= charArray[end];
        }
        return new string(charArray);
    }

如果你可以使用LINQ(。NET Framework 3.5+)而不是只跟随一行代码就可以得到简短的代码。不要忘记添加using System.Linq;来访问Enumerable。相反:

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

注:

不是最快的版本——根据马丁·尼德尔的说法,比最快的版本慢了5.7倍。 这段代码和许多其他选项一样,完全忽略了所有类型的多字符组合,因此只能在家庭作业和不包含此类字符的字符串中使用。有关正确处理此类组合的实现,请参阅本问题中的另一个答案。

有各种方法来反转字符串,我已经在下面展示了其中的3种。

——使用数组。反向作用。

 private static string ReverseString1(string text)
    {
        char[] rtext = text.ToCharArray();
        Array.Reverse(rtext);
        return new string(rtext);
    }

——只使用字符串

  private static string ReverseString2(string text)
    {
        String rtext = "";
        for (int i = text.Length - 1; i >= 0; i--)
        {
            rtext = rtext + text[i];
        }
        return rtext;
    }

——只使用char数组

 public static string ReverseString3(string str)
    {
        char[] chars = str.ToCharArray();
        char[] rchars = new char[chars.Length];
        for (int i = 0, j = str.Length - 1; i < chars.Length; i++, j--)
        {
            rchars[j] = chars[i];
        }
        return new string(rchars);
    }