要求:給定一個字符串,將字符串逆轉。例如給定“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
