问题描述
在.NET/C#编程开发中,将一个字符串翻转(即:reverse)的方法有很多,在低版本的.NET Framework中(比如.NET 2.0),LINQ
是不可用的。
在这种情况下,我们的实现就相对来说复杂一些,如:
public string Reverse(string text)
{
char[] cArray = text.ToCharArray();
string reverse = String.Empty;
for (int i = cArray.Length - 1; i > -1; i--)
{
reverse += cArray[i];
}
return reverse;
}
那么,在.NET/C#的编程开发中,还有没有其他的方式来实现将一个字符进行翻转的方法呢,哪种方法更好呢?
方案一
使用Array.Reverse()
方法,不需要使用for
循环,如下:
public static string Reverse( string s )
{
char[] charArray = s.ToCharArray();
Array.Reverse( charArray );
return new string( charArray );
}
方案二
在遇到一些特殊字符(或者特殊编码)的情况下,简单使用Array.Reverse()
方法并不好使,我们还需要对这些特殊字符进行处理,比如字符串"Les Mise\u0301rables"
,我们期望的翻转结果为selbarésiM seL
而不是selbare\u0301siM seL
,所以需要单独处理,如下:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
public static class Test
{
private static IEnumerable<string> GraphemeClusters(this string s) {
var enumerator = StringInfo.GetTextElementEnumerator(s);
while(enumerator.MoveNext()) {
yield return (string)enumerator.Current;
}
}
private static string ReverseGraphemeClusters(this string s) {
return string.Join("", s.GraphemeClusters().Reverse().ToArray());
}
public static void Main()
{
var s = "Les Mise\u0301rables";
var r = s.ReverseGraphemeClusters();
Console.WriteLine(r);
}
}
方案三
如果字符串中包含统一的字符编码标准(Unicode)的数据,我们同样也需要进行处理,如下:
public static string Reverse(this string input)
{
if (input == null)
throw new ArgumentNullException("input");
char[] output = new char[input.Length];
for (int outputIndex = 0, inputIndex = input.Length - 1; outputIndex < input.Length; outputIndex++, inputIndex--)
{
if (input[inputIndex] >= 0xDC00 && input[inputIndex] <= 0xDFFF &&
inputIndex > 0 && input[inputIndex - 1] >= 0xD800 && input[inputIndex - 1] <= 0xDBFF)
{
output[outputIndex + 1] = input[inputIndex];
output[outputIndex] = input[inputIndex - 1];
outputIndex++;
inputIndex--;
}
else
{
output[outputIndex] = input[inputIndex];
}
}
return new string(output);
}
方案四
在.NET Framework 3.5或者以上版本中,可以使用字符串的Reverse()
方法实现,如下:
public string ReverseString(string srtVarable)
{
return new string(srtVarable.Reverse().ToArray());
}
方案五
使用StringBuilder
的实现方案,如下:
public string Reverse(string text)
{
if (string.IsNullOrEmpty(text))
{
return text;
}
StringBuilder builder = new StringBuilder(text.Length);
for (int i = text.Length - 1; i >= 0; i--)
{
builder.Append(text[i]);
}
return builder.ToString();
}
方案六
使用string.Concat()
的实现方案,如下:
public static class StringExtensions
{
public static string Reverse(this string input)
{
return string.Concat(Enumerable.Reverse(input));
}
}
方案七
以下是包含了多种翻转字符串的方法以及性能对比测试,代码示例如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
public static string ReverseUsingArrayClass(string text)
{
char[] chars = text.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
public static string ReverseUsingCharacterBuffer(string text)
{
char[] charArray = new char[text.Length];
int inputStrLength = text.Length - 1;
for (int idx = 0; idx <= inputStrLength; idx++)
{
charArray[idx] = text[inputStrLength - idx];
}
return new string(charArray);
}
public static string ReverseUsingStringBuilder(string text)
{
if (string.IsNullOrEmpty(text))
{
return text;
}
StringBuilder builder = new StringBuilder(text.Length);
for (int i = text.Length - 1; i >= 0; i--)
{
builder.Append(text[i]);
}
return builder.ToString();
}
private static string ReverseUsingStack(string input)
{
Stack<char> resultStack = new Stack<char>();
foreach (char c in input)
{
resultStack.Push(c);
}
StringBuilder sb = new StringBuilder();
while (resultStack.Count > 0)
{
sb.Append(resultStack.Pop());
}
return sb.ToString();
}
public static string ReverseUsingXOR(string text)
{
char[] charArray = text.ToCharArray();
int length = text.Length - 1;
for (int i = 0; i < length; i++, length--)
{
charArray[i] ^= charArray[length];
charArray[length] ^= charArray[i];
charArray[i] ^= charArray[length];
}
return new string(charArray);
}
static void Main(string[] args)
{
string testString = string.Join(";", new string[] {
new string('a', 100),
new string('b', 101),
new string('c', 102),
new string('d', 103),
});
int cycleCount = 100000;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < cycleCount; i++)
{
ReverseUsingCharacterBuffer(testString);
}
stopwatch.Stop();
Console.WriteLine("ReverseUsingCharacterBuffer: " + stopwatch.ElapsedMilliseconds + "ms");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < cycleCount; i++)
{
ReverseUsingArrayClass(testString);
}
stopwatch.Stop();
Console.WriteLine("ReverseUsingArrayClass: " + stopwatch.ElapsedMilliseconds + "ms");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < cycleCount; i++)
{
ReverseUsingStringBuilder(testString);
}
stopwatch.Stop();
Console.WriteLine("ReverseUsingStringBuilder: " + stopwatch.ElapsedMilliseconds + "ms");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < cycleCount; i++)
{
ReverseUsingStack(testString);
}
stopwatch.Stop();
Console.WriteLine("ReverseUsingStack: " + stopwatch.ElapsedMilliseconds + "ms");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < cycleCount; i++)
{
ReverseUsingXOR(testString);
}
stopwatch.Stop();
Console.WriteLine("ReverseUsingXOR: " + stopwatch.ElapsedMilliseconds + "ms");
}
}
}
示例测试结果如下:
ReverseUsingCharacterBuffer: 346ms
ReverseUsingArrayClass: 87ms
ReverseUsingStringBuilder: 824ms
ReverseUsingStack: 2086ms
ReverseUsingXOR: 319ms
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册