字符串反转的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 stringoriginal)
{
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 stringoriginal)
{
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 stringoriginal)
{
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 = newStack<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 stringoriginal)
{
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 stringoriginal)
{
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());
}


转载地址:http://blog.sina.com.cn/s/blog_6997f0150100tpse.html

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.使用split()和reverse()方法: var str = "hello world"; var reverseStr = str.split("").reverse().join(""); 2.使用for循环和charAt()方法: var str = "hello world"; var reverseStr = ""; for (var i = str.length - 1; i >= 0; i--) { reverseStr += str.charAt(i); } 3.使用递归函数: function reverseString(str) { if (str === "") { return ""; } else { return reverseString(str.substr(1)) + str.charAt(0); } } var str = "hello world"; var reverseStr = reverseString(str); 4.使用reduce()方法: var str = "hello world"; var reverseStr = str.split("").reduce(function(rev, char) { return char + rev; }, ""); 5.使用spread operator和reverse()方法: var str = "hello world"; var reverseStr = [...str].reverse().join(""); 6.使用ES6的for-of循环和unshift()方法: var str = "hello world"; var reverseStr = ""; for (let char of str) { reverseStr = char + reverseStr; } 7.使用Array.from()方法和reverse()方法: var str = "hello world"; var reverseStr = Array.from(str).reverse().join(""); 8.使用Array.prototype.map()方法和reverse()方法: var str = "hello world"; var reverseStr = str.split("").map(function(char, i, arr) { return arr[arr.length - i - 1]; }).join(""); 9.使用Array.prototype.reduceRight()方法: var str = "hello world"; var reverseStr = str.split("").reduceRight(function(rev, char) { return rev + char; }, ""); 10.使用split()方法、join()方法和正则表达式: var str = "hello world"; var reverseStr = str.split(/\s*/).reverse().join("");

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值