c#字符串三種逆轉方法及性能比較


要求:給定一個字符串,將字符串逆轉。例如給定“welcome to caochao's blog  !”,要求輸出“!  golb s'oahcoac ot emoclew”。

初次看題時,想到的解法很可能就是倒序遍歷字符串,逐位取字符,然后拼成新字符串,新字符串即為逆轉后字符串。代碼如下:

     /// <summary>
        /// 字符串逆轉-StringBuilder實現
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReverseUsingStringBuilder(string str)
        {
            int length = str.Length;
            StringBuilder sb = new StringBuilder(length);

            for (int i = length - 1; i >= 0; i--)
            {
                sb.Append(str[i]);
            }
            return sb.ToString();
        }

 ,但其實,還有一種更為簡單的方法,簡單令人難以置信,看到這個方法時不得不驚嘆於.net framework方法的齊全。代碼如下:

         /// <summary>
        /// 字符串逆轉-CharArray實現
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReverseUsingCharArray(string str)
        {
            char[] arr = str.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }

  但仔細一想,也許還有種更快的,至少從原理上看起來應該會快點。這種方法從字符串兩端同時遍歷,再逐位交換值。代碼如下:

         /// <summary>
        /// 字符串逆轉-異或實現
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReverseUsingXor(string str)
        {
            char[] arr = str.ToCharArray();
            int l = str.Length - 1;

            //交換值
            for (int i = 0; i < l; i++, l--)
            {
                arr[i] ^= arr[l];
                arr[l] ^= arr[i];
                arr[i] ^= arr[l];
            }
            return new string(arr);
        }

  至此,講完了字符串逆轉的三種方法。也許看客還有更好的方法,就請在評論里留下您的高見吧。:-)

如同電影和電視劇時,最精彩的部分往往在后半部分。因此,小生的文章也把最重要的部分挪到了后面。筆者設計了一個測試方法,從而測試出以上三種字符串逆轉方法的性能優劣。該方法如下:

    public delegate string funcDelegate(string s);

        /// <summary>
        /// 測試方法
        /// </summary>
        /// <param name="description">方法描述</param>
        /// <param name="func">測試方法</param>
        /// <param name="times">執行次數</param>
        /// <param name="str">測試字符串</param>
        public static void Benchmark(string description, funcDelegate func, int times, string str)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int j = 0; j < times; j++)
            {
                func(str);
            }
            sw.Stop();
            Console.WriteLine("方法{0}:調用{1}次,用時{2}.", description, times, sw.ElapsedTicks);
        }

  還有一個生成隨機字符串的方法,請看代碼:

         /// <summary>
        /// 生成指定長度隨機字符串
        /// </summary>
        /// <param name="length">字條串長度</param>
        /// <returns></returns>
        public static string RandomString(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();
        }

  接下來,主角隆重登場。請看Main入口方法:

    static void Main(string[] args)
        {
            int[] lengths = new int[] { 1, 10, 15, 25, 50, 75, 100, 1000, 100000 };

            foreach (int len in lengths)
            {
                //每個方法都執行10000次,力求精確
                int iterations = 10000;

                //生成隨機測試字符串
                string testString = StringReverse.RandomString(len);

                //打印測試信息
                StringReverse.Benchmark(String.Format("String Builder (測試字符串長度為{0})", len), StringReverse.ReverseUsingStringBuilder, iterations, testString);
                StringReverse.Benchmark(String.Format("Array.Reverse (測試字符串長度為{0})", len), StringReverse.ReverseUsingCharArray, iterations, testString);
                StringReverse.Benchmark(String.Format("Xor (測試字符串長度為{0})", len), StringReverse.ReverseUsingXor, iterations, testString);

                Console.WriteLine();
            }
            Console.Read();
        }

  運行后看結果。結果在這里:

結論:從運行結果可以看出,

異或實現的逆轉方法,隨着字符串長度的遞增,用時越來越長。但在字符串長度較小時,為三種方法中性能最好的。

StringBuilder實現的字符串逆轉,無論字符串長度大小,都是性能最差的。個人估計是開辟新內存的開銷帶來的性能上的損失。

Array.Reverse實現的字符串逆轉,這種最傻瓜的方法,卻是在以上三種方法中性能表現最穩定的。個中原因,由看客們評價吧。

最后,附上stackoverflow上關於c#字符串逆轉算法的一個討論帖地址 

http://stackoverflow.com/questions/228038/best-way-to-reverse-a-string-in-c-sharp-2-0


免責聲明!

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



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