我刚刚在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;
}

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


当前回答

使用LINQ的聚合函数

string s = "Karthik U";
s = s.Aggregate(new StringBuilder(), (o, p) => o.Insert(0, p)).ToString();

其他回答

很抱歉在这个旧帖子上发帖。我在为面试练习一些代码。

这是我为c#设计的。在重构之前,我的第一个版本非常糟糕。

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

对比数组。相反的方法下面,它出现更快的12个字符或更少的字符串。13个字符后,数组。倒车开始变得更快,最终在速度上占主导地位。我只是想指出速度开始变化的大致位置。

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

    Array.Reverse(charA);

    return new String(charA);
}

在字符串中有100个字符时,它比我的版本x 4快。然而,如果我知道字符串总是小于13个字符,我就会使用我所创建的字符串。

测试使用Stopwatch进行,并进行了500万次迭代。此外,我不确定我的版本是否处理代理或组合字符情况与Unicode编码。

如果在面试中你被告知不能使用Array。反过来,我想这可能是最快的一个。它不会创建新的字符串,只迭代数组的一半以上(即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);
    }

基于堆栈的解决方案。

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

Or

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

看看维基百科的条目。它们实现了字符串。反向扩展法。这允许你编写这样的代码:

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

他们还使用ToCharArray/Reverse组合,这是这个问题的其他答案所建议的。源代码如下所示:

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

在使用StringInfo.GetTextElementEnumerator()的地方有几个正确答案。向你致敬!

现在,让我们找出最有效的方法来使用这个方法。首先,大多数答案涉及调用Reverse()和ToArray(),这在热路径上是一个大禁忌。为了获得最佳性能,我们希望避免分配垃圾。例如,临时字符串,分配器,数组等。

优化的管柱反转

降低气相色谱压力。也就是说,没有LINQ枚举器,没有数组。 使用跨 使用String.Create ()

using System.Globalization;

public static class StringExtensions
{
    public static string AsReversed(this string s)
    {
        return string.Create(s.Length, s, (chars, state) =>
        {
            int i = 0;
            var enumerator = StringInfo.GetTextElementEnumerator(s);
            while (enumerator.MoveNext())
            {
                var element = enumerator.GetTextElement();
                i += element.Length;
                element.CopyTo(chars[^i..]);
            }
        });
    }
}

请注意,GetTextElementEnumerator() API在. net Core 3.1和更早的版本中包含一个错误。确保运行。net 5或更高版本!最后,请务必查看正在讨论API改进的问题#19423。