字符串反转的9种⽅法
转⾃:
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;
}c++中string的用法
}
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[] CharArray();
for(int i=cs.length-1;i>=0;i--)
{
s2=s2+cs[i];
}
System.out.println("对字符串进⾏反转操作后为:"+s2);
StringBuffer sb=new StringBuffer("abcdefg");
StringBuffer verse();
System.out.println("对StringBuffer进⾏反转操作后为:"+sb2); }
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论