我刚刚在c# 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;
}
就我个人而言,我并不喜欢这个功能,我相信有更好的方法来实现它。是吗?
如果字符串包含Unicode数据(严格地说,非bmp字符),其他已经发布的方法将破坏它,因为在反转字符串时不能交换高和低代理代码单元的顺序。(关于这方面的更多信息可以在我的博客上找到。)
下面的代码示例将正确地反转包含非bmp字符的字符串,例如,“\U00010380\U00010381”(ugartic Letter Alpa, ugartic Letter Beta)。
public static string Reverse(this string input)
{
if (input == null)
throw new ArgumentNullException("input");
// allocate a buffer to hold the output
char[] output = new char[input.Length];
for (int outputIndex = 0, inputIndex = input.Length - 1; outputIndex < input.Length; outputIndex++, inputIndex--)
{
// check for surrogate pair
if (input[inputIndex] >= 0xDC00 && input[inputIndex] <= 0xDFFF &&
inputIndex > 0 && input[inputIndex - 1] >= 0xD800 && input[inputIndex - 1] <= 0xDBFF)
{
// preserve the order of the surrogate pair code units
output[outputIndex + 1] = input[inputIndex];
output[outputIndex] = input[inputIndex - 1];
outputIndex++;
inputIndex--;
}
else
{
output[outputIndex] = input[inputIndex];
}
}
return new string(output);
}
首先,你必须理解的是str+=将调整字符串内存大小,为1个额外的字符腾出空间。这很好,但是如果你有一本1000页的书,你想要反转,这将需要很长时间来执行。
有些人建议的解决方案是使用StringBuilder。字符串构建器在执行+=时所做的是分配更大的内存块来保存新字符,这样它就不需要在每次添加字符时进行重新分配。
如果你真的想要一个快速和最小的解决方案,我建议如下:
char[] chars = new char[str.Length];
for (int i = str.Length - 1, j = 0; i >= 0; --i, ++j)
{
chars[j] = str[i];
}
str = new String(chars);
在这个解决方案中,在初始化char[]时有一个初始内存分配,在string构造函数从char数组构建字符串时有一个初始内存分配。
在我的系统上,我为您运行了一个测试,反转了一个2750,000个字符的字符串。以下是10次执行的结果:
StringBuilder: 190K - 200K tick
字符数组:130K - 160K
我还运行了一个正常String +=的测试,但我在10分钟后放弃了它,没有输出。
但是,我也注意到,对于较小的字符串,StringBuilder更快,因此您必须根据输入来决定实现。
干杯