字符串反轉的9種方法

轉自:http://blog.sina.com.cn/s/blog_6997f0150100tpse.htmlhtml

 

1. 使用Array.Reverse方法

對於字符串反轉,咱們可使用.NET類庫自帶的Array.Reverse方法

public static string ReverseByArray(string original)
{
char[] c = original.ToCharArray();
Array.Reverse(c);
return new string(c);
}

2. 使用字符緩存

在面試或筆試中,每每要求不用任何類庫方法,那麼有朋友大概會使用相似下面這樣的循環方法

public static string ReverseByCharBuffer(this string original)
{
char[] c = original.ToCharArray();
int l = original.Length;
char[] o = new char[l];
for (int i = 0; i < l ; i++)
{
o[i] = c[l - i - 1];
}
return new string(o);
}

固然,聰明的同窗們必定會發現沒必要對這個字符數組進行徹底遍歷,一般狀況下咱們會只遍歷一半

public static string ReverseByCharBuffer2(string original)
{
char[] c = original.ToCharArray();
int l = original.Length;
for (int i = 0; i < l / 2; i++)
{
char t = c[i];
c[i] = c[l - i - 1];
c[l - i - 1] = t;
}
return new string(c);
}

ReverseByCharBuffer使用了一個新的數組,並且遍歷了字符數組的全部元素,所以時間和空間的開銷都要大於ReverseByCharBuffer2。

在Array.Reverse內部,調用了非託管方法TrySZReverse,若是TrySZReverse不成功,實際上也是調用了相似ReverseByCharBuffer2的方法。

if (!TrySZReverse(array, index, length))
{
int num = index;
int num2 = (index + length) - 1;
object[] objArray = array as object[];
if (objArray == null)
{
while (num < num2)
{
object obj3 = array.GetValue(num);
array.SetValue(array.GetValue(num2), num);
array.SetValue(obj3, num2);
num++;
num2--;
}
}
else
{
while (num < num2)
{
object obj2 = objArray[num];
objArray[num] = objArray[num2];
objArray[num2] = obj2;
num++;
num2--;
}
}
}

大體上我能想到的算法就是這麼多了,可是我無心間發現了StackOverflow上的一篇帖子,才發現這麼一個看似簡單的反轉算法實現起來真可謂花樣繁多。
3. 使用StringBuilder

使用StringBuilder方法大體和ReverseByCharBuffer同樣,只不過不使用字符數組作緩存,而是使用StringBuilder。

public static string ReverseByStringBuilder(this string original)
{
StringBuilder sb = new StringBuilder(original.Length);
for (int i = original.Length - 1; i >= 0; i--)
{
sb.Append(original[i]);
}
return sb.ToString();
}

固然,你能夠預見,這種算法的效率不會比ReverseByCharBuffer要高。

咱們能夠像使用字符緩存那樣,對使用StringBuilder方法進行優化,使其遍歷過程也減小一半

public static string ReverseByStringBuilder2(this string original)
{
StringBuilder sb = new StringBuilder(original);
for (int i = 0, j = original.Length - 1; i <= j; i++, j--)
{
sb[i] = original[j];
sb[j] = original[i];
}
return sb.ToString();
}

以上這幾種方法按算法角度來講,其實能夠歸結爲一類。然而下面的幾種算法就徹底不是同一類型的了。
使用棧

4. 棧是一個很神奇的數據結構。咱們可使用它後進先出的特性來對數組進行反轉。先將數組全部元素壓入棧,而後再取出,順序很天然地就與原先相反了。

public static string ReverseByStack(this string original)
{
Stack<char> stack = new Stack<char>();
foreach (char ch in original)
{
stack.Push(ch);
}
char[] c = new char[original.Length];
for (int i = 0; i < original.Length; i++)
{
c[i] = stack.Pop();
}
return new string(c);
}

兩次循環和棧的開銷無疑使這種方法成爲目前爲止開銷最大的方法。但使用棧這個數據結構的想法仍是很是有價值的。
使用XOR

5. 使用邏輯異或也能夠進行反轉

public static string ReverseByXor(string original)
{
char[] charArray = original.ToCharArray();
int l = original.Length - 1;
for (int i = 0; i < l; i++, l--)
{
charArray[i] ^= charArray[l];
charArray[l] ^= charArray[i];
charArray[i] ^= charArray[l];
}
return new string(charArray);
}

在C#中,x ^= y至關於x = x ^ y。經過3次異或操做,能夠將兩個字符爲止互換。對於算法具體的解釋能夠參考這篇文章。
6. 使用指針

使用指針能夠達到最快的速度,可是unsafe代碼不是微軟所推薦的,在這裏咱們就很少作討論了

public static unsafe string ReverseByPointer(this string original)
{
fixed (char* pText = original)
{
char* pStart = pText;
char* pEnd = pText + original.Length - 1;
for (int i = original.Length / 2; i >= 0; i--)
{
char temp = *pStart;
*pStart++ = *pEnd;
*pEnd-- = temp;
}

return original;
}
}

7. 使用遞歸

對於反轉這類算法,均可以使用遞歸方法

public static string ReverseByRecursive(string original)
{
if (original.Length == 1)
return original;
else
return original.Substring(1).ReverseByRecursive() + original[0];
}

8. 使用委託,還可使代碼變得更加簡潔

public static string ReverseByRecursive2(this string original)
{
Func<string, string> f = null;
f = s => s.Length > 0 ? f(s.Substring(1)) + s[0] : string.Empty;
return f(original);
}

可是委託開銷大的弊病在這裏一點也沒有減小,以致於我作性能測試的時候致使系統假死甚至內存益處。
使用LINQ

9. System.Enumerable裏提供了默認的Reverse擴展方法,咱們能夠基於該方法來對String類型進行擴展

public static string ReverseByLinq(this string original)
{
return new string(original.Reverse().ToArray());
}面試

10.經過char數組的方式遍歷反轉:算法

package string;

public class StringTest3 {
public static void main(String[] args)
{
String s="abcdefg";
String s2="";
char[] cs=s.toCharArray();
for(int i=cs.length-1;i>=0;i--)
{
s2=s2+cs[i];
}
System.out.println("對字符串進行反轉操做後爲:"+s2);
StringBuffer sb=new StringBuffer("abcdefg");
StringBuffer sb2=sb.reverse();
System.out.println("對StringBuffer進行反轉操做後爲:"+sb2);
}

}
相關文章
相關標籤/搜索