反转string的最佳方法

我只是不得不在C#2.0中编写一个string反向函数(即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; } 

就我个人而言,我并不是对这个function感到兴奋,而是相信有更好的方法去做。 在那儿?

 public static string Reverse( string s ) { char[] charArray = s.ToCharArray(); Array.Reverse( charArray ); return new string( charArray ); } 

这里有一个解决scheme,正确地将string"Les Mise\u0301rables"反转为"selbare\u0301siM seL" 。 这应该像selbarésiM seL一样渲染,而不是selbaŕesiM seL (注意重音的位置),大多数基于代码单元( Array.Reverse等)的实现的结果,甚至是代码点(特别注意代理对)。

 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); } } 

(现场运行示例: https : //ideone.com/DqAeMJ )

它只是使用.NET API来进行字素集群迭代 ,它自从曾经存在,但看起来有点“隐藏”。

这是一个令人惊讶的棘手问题。

对于大多数情况,我build议使用Array.Reverse,因为它本身是编码的,维护和理解起来非常简单。

在我testing的所有情况下,似乎都超过了StringBuilder。

 public string Reverse(string text) { if (text == null) return null; // this was posted by petebob as well char[] array = text.ToCharArray(); Array.Reverse(array); return new String(array); } 

对于某些使用Xor的string长度,还有一种方法可以更快。

  public static string ReverseXor(string s) { if (s == null) return null; char[] charArray = s.ToCharArray(); int len = s.Length - 1; for (int i = 0; i < len; i++, len--) { charArray[i] ^= charArray[len]; charArray[len] ^= charArray[i]; charArray[i] ^= charArray[len]; } return new string(charArray); } 

注意如果你想支持完整的Unicode UTF16字符集, 请阅读此内容 。 然后使用那里的实现。 可以通过使用上述algorithm之一进一步优化,并在字符反转后通过string运行来清理它。

以下是StringBuilder,Array.Reverse和Xor方法之间的性能比较。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; namespace ConsoleApplication4 { class Program { delegate string StringDelegate(string s); static void Benchmark(string description, StringDelegate d, int times, string text) { Stopwatch sw = new Stopwatch(); sw.Start(); for (int j = 0; j < times; j++) { d(text); } sw.Stop(); Console.WriteLine("{0} Ticks {1} : called {2} times.", sw.ElapsedTicks, description, times); } public static string ReverseXor(string s) { char[] charArray = s.ToCharArray(); int len = s.Length - 1; for (int i = 0; i < len; i++, len--) { charArray[i] ^= charArray[len]; charArray[len] ^= charArray[i]; charArray[i] ^= charArray[len]; } return new string(charArray); } public static string ReverseSB(string text) { StringBuilder builder = new StringBuilder(text.Length); for (int i = text.Length - 1; i >= 0; i--) { builder.Append(text[i]); } return builder.ToString(); } public static string ReverseArray(string text) { char[] array = text.ToCharArray(); Array.Reverse(array); return (new string(array)); } public static string StringOfLength(int length) { Random random = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.Append(Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)))); } return sb.ToString(); } static void Main(string[] args) { int[] lengths = new int[] {1,10,15,25,50,75,100,1000,100000}; foreach (int l in lengths) { int iterations = 10000; string text = StringOfLength(l); Benchmark(String.Format("String Builder (Length: {0})", l), ReverseSB, iterations, text); Benchmark(String.Format("Array.Reverse (Length: {0})", l), ReverseArray, iterations, text); Benchmark(String.Format("Xor (Length: {0})", l), ReverseXor, iterations, text); Console.WriteLine(); } Console.Read(); } } } 

结果如下:

 26251 Ticks String Builder (Length: 1) : called 10000 times. 33373 Ticks Array.Reverse (Length: 1) : called 10000 times. 20162 Ticks Xor (Length: 1) : called 10000 times. 51321 Ticks String Builder (Length: 10) : called 10000 times. 37105 Ticks Array.Reverse (Length: 10) : called 10000 times. 23974 Ticks Xor (Length: 10) : called 10000 times. 66570 Ticks String Builder (Length: 15) : called 10000 times. 26027 Ticks Array.Reverse (Length: 15) : called 10000 times. 24017 Ticks Xor (Length: 15) : called 10000 times. 101609 Ticks String Builder (Length: 25) : called 10000 times. 28472 Ticks Array.Reverse (Length: 25) : called 10000 times. 35355 Ticks Xor (Length: 25) : called 10000 times. 161601 Ticks String Builder (Length: 50) : called 10000 times. 35839 Ticks Array.Reverse (Length: 50) : called 10000 times. 51185 Ticks Xor (Length: 50) : called 10000 times. 230898 Ticks String Builder (Length: 75) : called 10000 times. 40628 Ticks Array.Reverse (Length: 75) : called 10000 times. 78906 Ticks Xor (Length: 75) : called 10000 times. 312017 Ticks String Builder (Length: 100) : called 10000 times. 52225 Ticks Array.Reverse (Length: 100) : called 10000 times. 110195 Ticks Xor (Length: 100) : called 10000 times. 2970691 Ticks String Builder (Length: 1000) : called 10000 times. 292094 Ticks Array.Reverse (Length: 1000) : called 10000 times. 846585 Ticks Xor (Length: 1000) : called 10000 times. 305564115 Ticks String Builder (Length: 100000) : called 10000 times. 74884495 Ticks Array.Reverse (Length: 100000) : called 10000 times. 125409674 Ticks Xor (Length: 100000) : called 10000 times. 

看来Xor对于短string可以更快。

如果string包含Unicode数据(严格来说,非BMP字符),则其他已发布的方法将会破坏该string,因为在颠倒string时无法交换高位和低位代理单元的顺序。 (关于这方面的更多信息可以在我的博客上find。)

以下代码示例将正确地反转包含非BMP字符的string,例如,“\ U00010380 \ U00010381”(Ugaritic Letter Alpa,Ugaritic 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); } 

从3.5以上的框架

 public string ReverseString(string srtVarable) { return new string(srtVarable.Reverse().ToArray()); } 

好吧,为了“不要重复自己”,我提供了以下解决scheme:

 public string Reverse(string text) { return Microsoft.VisualBasic.Strings.StrReverse(text); } 

我的理解是,这种实现,在VB.NET中默认可用,正确处理Unicode字符。

格雷格·比奇(Greg Beech)发布了一个unsafeselect,其速度确实非常快(这是一个原地反转)。 但正如他在答复中所表示的那样,这是一个完全灾难性的主意

这就是说,我很惊讶有这么多的共识, Array.Reverse是最快的方法。 还有一种unsafe方法,它会返回一个string的反转副本(没有in-place reversal shenanigans) ,比小型stringArray.Reverse方法快得多

 public static unsafe string Reverse(string text) { int len = text.Length; // Why allocate a char[] array on the heap when you won't use it // outside of this method? Use the stack. char* reversed = stackalloc char[len]; // Avoid bounds-checking performance penalties. fixed (char* str = text) { int i = 0; int j = i + len - 1; while (i < len) { reversed[i++] = str[j--]; } } // Need to use this overload for the System.String constructor // as providing just the char* pointer could result in garbage // at the end of the string (no guarantee of null terminator). return new string(reversed, 0, len); } 

以下是一些基准testing结果 。

当string变大时,你可以看到性能增益收缩,然后消失在Array.Reverse方法中。 但是,对于中小型琴弦来说,很难击败这种方法。

如果你想玩一个非常危险的游戏,那么这是迄今为止最快的方式(比Array.Reverse方法快Array.Reverse )。 这是一个使用指针的就地反转。

请注意,我真的不推荐这个用于任何用途,( 有一些原因,这里为什么你不应该使用这种方法 ),但它是有趣的,看到它可以完成,并且string不是真正不可变的一旦你打开不安全的代码。

 public static unsafe string Reverse(string text) { if (string.IsNullOrEmpty(text)) { return text; } fixed (char* pText = text) { char* pStart = pText; char* pEnd = pText + text.Length - 1; for (int i = text.Length / 2; i >= 0; i--) { char temp = *pStart; *pStart++ = *pEnd; *pEnd-- = temp; } return text; } } 

首先你不需要调用ToCharArray因为一个string已经可以被索引为一个char数组,所以这将为你节省一个分配。

下一个优化是使用一个StringBuilder来防止不必要的分配(因为string是不可变的,连接它们每次都会产生一个string的副本)。 为了进一步优化,我们预先设置了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(); } 

编辑:性能数据

我testing了这个函数和函数使用Array.Reverse与以下简单的程序,其中Reverse1是一个function, Reverse2是另一个:

 static void Main(string[] args) { var text = "abcdefghijklmnopqrstuvwxyz"; // pre-jit text = Reverse1(text); text = Reverse2(text); // test var timer1 = Stopwatch.StartNew(); for (var i = 0; i < 10000000; i++) { text = Reverse1(text); } timer1.Stop(); Console.WriteLine("First: {0}", timer1.ElapsedMilliseconds); var timer2 = Stopwatch.StartNew(); for (var i = 0; i < 10000000; i++) { text = Reverse2(text); } timer2.Stop(); Console.WriteLine("Second: {0}", timer2.ElapsedMilliseconds); Console.ReadLine(); } 

事实certificate,对于短string, Array.Reverse方法的速度是上面的两倍,对于较长的string,差异更加明显。 所以鉴于Array.Reverse方法是更简单和更快,我build议你使用,而不是这一个。 我把这个留在这里只是为了表明这不是你应该这样做的方式(令我吃惊的是!)

简单而好的答案是使用扩展方法:

 static class ExtentionMethodCollection { public static string Inverse(this string @base) { return new string(@base.Reverse().ToArray()); } } 

这里是输出:

 string Answer = "12345".Inverse(); // = "54321" 

尝试使用Array.Reverse

 public string Reverse(string str) { char[] array = str.ToCharArray(); Array.Reverse(array); return new string(array); } 
 public static string Reverse(string input) { return string.Concat(Enumerable.Reverse(input)); } 

当然,你可以用Reverse方法扩展string类

 public static class StringExtensions { public static string Reverse(this string input) { return string.Concat(Enumerable.Reverse(input)); } } 

看看这里的维基百科条目。 他们实现了String.Reverse扩展方法。 这允许你写这样的代码:

 string s = "olleh"; s.Reverse(); 

他们也使用ToCharArray / Reverse组合来解决这个问题的其他答案。 源代码如下所示:

 public static string Reverse(this string input) { char[] chars = input.ToCharArray(); Array.Reverse(chars); return new String(chars); } 

不要打扰一个function,只是做到位。 注意:第二行会在一些VS版本的立即窗口中抛出一个参数exception。

 string s = "Blah"; s = new string(s.ToCharArray().Reverse().ToArray()); 

必须提交一个recursion的例子:

 private static string Reverse(string str) { if (str.IsNullOrEmpty(str) || str.Length == 1) return str; else return str[str.Length - 1] + Reverse(str.Substring(0, str.Length - 1)); } 

对不起,很长的文章,但这可能是有趣的

 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

基于堆栈的解决scheme。

  public static string Reverse(string text) { var stack = new Stack<char>(text); var array = new char[stack.Count]; int i = 0; while (stack.Count != 0) { array[i++] = stack.Pop(); } return new string(array); } 

要么

  public static string Reverse(string text) { var stack = new Stack<char>(text); return string.Join("", stack); } 

怎么样:

  private string Reverse(string stringToReverse) { char[] rev = stringToReverse.Reverse().ToArray(); return new string(rev); } 
 public string Reverse(string input) { char[] output = new char[input.Length]; int forwards = 0; int backwards = input.Length - 1; do { output[forwards] = input[backwards]; output[backwards] = input[forwards]; }while(++forwards <= --backwards); return new String(output); } public string DotNetReverse(string input) { char[] toReverse = input.ToCharArray(); Array.Reverse(toReverse); return new String(toReverse); } public string NaiveReverse(string input) { char[] outputArray = new char[input.Length]; for (int i = 0; i < input.Length; i++) { outputArray[i] = input[input.Length - 1 - i]; } return new String(outputArray); } public string RecursiveReverse(string input) { return RecursiveReverseHelper(input, 0, input.Length - 1); } public string RecursiveReverseHelper(string input, int startIndex , int endIndex) { if (startIndex == endIndex) { return "" + input[startIndex]; } if (endIndex - startIndex == 1) { return "" + input[endIndex] + input[startIndex]; } return input[endIndex] + RecursiveReverseHelper(input, startIndex + 1, endIndex - 1) + input[startIndex]; } void Main() { int[] sizes = new int[] { 10, 100, 1000, 10000 }; for(int sizeIndex = 0; sizeIndex < sizes.Length; sizeIndex++) { string holaMundo = ""; for(int i = 0; i < sizes[sizeIndex]; i+= 5) { holaMundo += "ABCDE"; } string.Format("\n**** For size: {0} ****\n", sizes[sizeIndex]).Dump(); string odnuMaloh = DotNetReverse(holaMundo); var stopWatch = Stopwatch.StartNew(); string result = NaiveReverse(holaMundo); ("Naive Ticks: " + stopWatch.ElapsedTicks).Dump(); stopWatch.Restart(); result = Reverse(holaMundo); ("Efficient linear Ticks: " + stopWatch.ElapsedTicks).Dump(); stopWatch.Restart(); result = RecursiveReverse(holaMundo); ("Recursive Ticks: " + stopWatch.ElapsedTicks).Dump(); stopWatch.Restart(); result = DotNetReverse(holaMundo); ("DotNet Reverse Ticks: " + stopWatch.ElapsedTicks).Dump(); } } 

产量

大小:10

 Naive Ticks: 1 Efficient linear Ticks: 0 Recursive Ticks: 2 DotNet Reverse Ticks: 1 

大小:100

 Naive Ticks: 2 Efficient linear Ticks: 1 Recursive Ticks: 12 DotNet Reverse Ticks: 1 

大小:1000

 Naive Ticks: 5 Efficient linear Ticks: 2 Recursive Ticks: 358 DotNet Reverse Ticks: 9 

大小:10000

 Naive Ticks: 32 Efficient linear Ticks: 28 Recursive Ticks: 84808 DotNet Reverse Ticks: 33 

我从Microsoft.VisualBasic.Strings做了一个C#端口。 我不知道为什么他们保持这样有用的function(从VB)以外的System.String框架,但仍然在Microsoft.VisualBasic下。 财务职能相同(例如Microsoft.VisualBasic.Financial.Pmt() )。

 public static string StrReverse(this string expression) { if ((expression == null)) return ""; int srcIndex; var length = expression.Length; if (length == 0) return ""; //CONSIDER: Get System.String to add a surrogate aware Reverse method //Detect if there are any graphemes that need special handling for (srcIndex = 0; srcIndex <= length - 1; srcIndex++) { var ch = expression[srcIndex]; var uc = char.GetUnicodeCategory(ch); if (uc == UnicodeCategory.Surrogate || uc == UnicodeCategory.NonSpacingMark || uc == UnicodeCategory.SpacingCombiningMark || uc == UnicodeCategory.EnclosingMark) { //Need to use special handling return InternalStrReverse(expression, srcIndex, length); } } var chars = expression.ToCharArray(); Array.Reverse(chars); return new string(chars); } ///<remarks>This routine handles reversing Strings containing graphemes /// GRAPHEME: a text element that is displayed as a single character</remarks> private static string InternalStrReverse(string expression, int srcIndex, int length) { //This code can only be hit one time var sb = new StringBuilder(length) { Length = length }; var textEnum = StringInfo.GetTextElementEnumerator(expression, srcIndex); //Init enumerator position if (!textEnum.MoveNext()) { return ""; } var lastSrcIndex = 0; var destIndex = length - 1; //Copy up the first surrogate found while (lastSrcIndex < srcIndex) { sb[destIndex] = expression[lastSrcIndex]; destIndex -= 1; lastSrcIndex += 1; } //Now iterate through the text elements and copy them to the reversed string var nextSrcIndex = textEnum.ElementIndex; while (destIndex >= 0) { srcIndex = nextSrcIndex; //Move to next element nextSrcIndex = (textEnum.MoveNext()) ? textEnum.ElementIndex : length; lastSrcIndex = nextSrcIndex - 1; while (lastSrcIndex >= srcIndex) { sb[destIndex] = expression[lastSrcIndex]; destIndex -= 1; lastSrcIndex -= 1; } } return sb.ToString(); } 

“更好的方式”取决于在你的情况,性能,优雅,可维护性等方面对你更重要的东西。

无论如何,这里有一个使用Array.Reverse的方法:

 string inputString="The quick brown fox jumps over the lazy dog."; char[] charArray = inputString.ToCharArray(); Array.Reverse(charArray); string reversed = new string(charArray); 

If you have a string that only contains ASCII characters, you can use this method.

  public static string ASCIIReverse(string s) { byte[] reversed = new byte[s.Length]; int k = 0; for (int i = s.Length - 1; i >= 0; i--) { reversed[k++] = (byte)s[i]; } return Encoding.ASCII.GetString(reversed); } 
 public static string reverse(string s) { string r = ""; for (int i = s.Length; i > 0; i--) r += s[i - 1]; return r; } 

As simple as this:

 string x = "your string"; string x1 = ""; for(int i = x.Length-1 ; i >= 0; i--) x1 += x[i]; Console.WriteLine("The reverse of the string is:\n {0}", x1); 

See the output .

If it ever came up in an interview and you were told you can't use Array.Reverse, i think this might be one of the fastest. It does not create new strings and iterates only over half of the array (ie O(n/2) iterations)

  public static string ReverseString(string stringToReverse) { char[] charArray = stringToReverse.ToCharArray(); int len = charArray.Length-1; int mid = len / 2; for (int i = 0; i < mid; i++) { char tmp = charArray[i]; charArray[i] = charArray[len - i]; charArray[len - i] = tmp; } return new string(charArray); } 
 public static string Reverse2(string x) { char[] charArray = new char[x.Length]; int len = x.Length - 1; for (int i = 0; i <= len; i++) charArray[i] = x[len - i]; return new string(charArray); } 
 private static string Reverse(string str) { string revStr = string.Empty; for (int i = str.Length - 1; i >= 0; i--) { revStr += str[i].ToString(); } return revStr; } 

Faster than above method

 private static string ReverseEx(string str) { char[] chrArray = str.ToCharArray(); int len = chrArray.Length - 1; char rev = 'n'; for (int i = 0; i <= len/2; i++) { rev = chrArray[i]; chrArray[i] = chrArray[len - i]; chrArray[len - i] = rev; } return new string(chrArray); } 
  string original = "Stack Overflow"; string reversed = new string(original.Reverse().ToArray()); 

First of all what you have to understand is that str+= will resize your string memory to make space for 1 extra char. This is fine, but if you have, say, a book with 1000 pages that you want to reverse, this will take very long to execute.

The solution that some people might suggest is using StringBuilder. What string builder does when you perform a += is that it allocates much larger chunks of memory to hold the new character so that it does not need to do a reallocation every time you add a char.

If you really want a fast and minimal solution I'd suggest the following:

  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); 

In this solution there is one initial memory allocation when the char[] is initialized and one allocation when the string constructor builds the string from the char array.

On my system I ran a test for you that reverses a string of 2 750 000 characters. Here are the results for 10 executions:

StringBuilder: 190K – 200K ticks

Char Array: 130K – 160K ticks

I also ran a test for normal String += but I abandoned it after 10 minutes with no output.

However, I also noticed that for smaller strings the StringBuilder is faster, so you will have to decide on the implementation based on the input.

干杯

Sorry for posting on this old thread. I am practicing some code for an interview.

This was what I came up with for C#. My first version before refactoring was horrible.

 static String Reverse2(string str) { int strLen = str.Length, elem = strLen - 1; char[] charA = new char[strLen]; for (int i = 0; i < strLen; i++) { charA[elem] = str[i]; elem--; } return new String(charA); } 

In Contrast to the Array.Reverse method below, it appears faster with 12 characters or less in the string. After 13 characters, the Array.Reverse starts to get faster, and it eventually dominates pretty heavily on speed. I just wanted to point out approximately where the speed starts to change.

 static String Reverse(string str) { char[] charA = str.ToCharArray(); Array.Reverse(charA); return new String(charA); } 

At 100 characters in the string, it is faster than my version x 4. However, if I knew that the strings would always be less than 13 characters, I would use the one I made.

Testing was done with Stopwatch and 5000000 iterations. Also, I'm not sure if my version handles Surrogates or combined character situations with Unicode encoding.