C#編程實踐--字符串反轉


朴素反轉

朴素解法,倒序遍歷,字符串拼接,字符串性能低下,在長度已知的前提可以使用char數組代替

public static string NaiveReverse(string text)
{
    string reverse = string.Empty;
    for (int i = text.Length - 1; i >= 0; i--)
    {
        reverse += text[i];
    }

    return reverse;
}

StringBuilder拼接

進一步改進,使用StringBuilder進行拼接字符串

public static string SBReverse(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 BinaryReverse(string text)
{
    char[] charArray = text.ToCharArray();
    int len = text.Length - 1;

    for (int i = 0; i < len; i++, len--)
    {
        char tmp = charArray[i];
        charArray[i] = charArray[len];
        charArray[len] = tmp;
    }

    return new string(charArray);
}

指針操作

咦?字符串居然可變?

public static unsafe string UnsafeReverse(string 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;
    }
}

數組反轉

最容易理解的方式,往往是最高效的,為啥這么高效?

public static string ArrayReverse(string text)
{
    char[] charArray = text.ToCharArray();
    Array.Reverse(charArray);

    return new string(charArray);
}

XOR操作

是不是很有逼格?其實對於理解位操作還是有點幫助,至於性能嘛。。。

public static string XorReverse(string text)
{
    char[] charArray = text.ToCharArray();
    int len = text.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);
}

FCL實現

升級到.NET3.5了嗎?OK,最少的代碼實現,可是性能嘛,額

public static string EnumReverse(string text)
{
    char[] reverse = text.Reverse().ToArray();

    return new string(reverse);
}

 

測試

Stopwatch watcher = new Stopwatch();
// 字符串規模
int[] sizes = new[] { 10, 100, 1000, 10000 };
// 反轉方法列表
var ReverseMethods = new Func<string, string>[]
{
    NaiveReverse,
    SBReverse,
    BinaryReverse,
    UnsafeReverse,
    ArrayReverse,
    XorReverse,
    EnumReverse
};

for (int i = 0; i < sizes.Length; i++)
{
    string text = new string('X', sizes[i]);

    Console.WriteLine("For Size: {0}", sizes[i]);
    for (int j = 0; j < ReverseMethods.Length; j++)
    {
        var invoker = ReverseMethods[j];

        watcher.Restart();
        invoker(text);
        watcher.Stop();
        Console.WriteLine("{0} Ticks: {1}", invoker.Method.Name, watcher.ElapsedTicks);
    }
    Console.WriteLine();
}

Console.ReadLine();

 

結語

寫這些代碼到底有什么意義?性能到底如何?好了,那么問題來了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM