ReverseString, a C# interview-question

前端 未结 12 1846
予麋鹿
予麋鹿 2021-01-31 06:15

I had an interview question that asked me for my \'feedback\' on a piece of code a junior programmer wrote. They hinted there may be a problem and said it will be used heavily o

相关标签:
12条回答
  • 2021-01-31 07:08

    The problem is that string concatenations are expensive to do as strings are immutable in C#. The example given will create a new string one character longer each iteration which is very inefficient. To avoid this you should use the StringBuilder class instead like so:

    public string ReverseString(string sz)
    {
        var builder = new StringBuilder(sz.Length);
        for(int i = sz.Length-1; i>=0; i--)
        {
          builder.Append(sz[i]);
        }
        return builder.ToString();
    }
    

    The StringBuilder is written specifically for scenarios like this as it gives you the ability to concatenate strings without the drawback of excessive memory allocation.

    You will notice I have provided the StringBuilder with an initial capacity which you don't often see. As you know the length of the result to begin with, this removes needless memory allocations.

    What normally happens is it allocates an amount of memory to the StringBuilder (default 16 characters). Once the contents attempts to exceed that capacity it doubles (I think) its own capactity and carries on. This is much better than allocating memory each time as would happen with normal strings, but if you can avoid this as well it's even better.

    0 讨论(0)
  • 2021-01-31 07:09

    Most importantly? That will suck performance wise - it has to create lots of strings (one per character). The simplest way is something like:

    public static string Reverse(string sz) // ideal for an extension method
    {
        if (string.IsNullOrEmpty(sz) || sz.Length == 1) return sz;
        char[] chars = sz.ToCharArray();
        Array.Reverse(chars);
        return new string(chars);
    }
    
    0 讨论(0)
  • 2021-01-31 07:14

    A few comments on the answers given so far:

    • Every single one of them (so far!) will fail on surrogate pairs and combining characters. Oh the joys of Unicode. Reversing a string isn't the same as reversing a sequence of chars.
    • I like Marc's optimisation for null, empty, and single character inputs. In particular, not only does this get the right answer quickly, but it also handles null (which none of the other answers do)
    • I originally thought that ToCharArray followed by Array.Reverse would be the fastest, but it does create one "garbage" copy.
    • The StringBuilder solution creates a single string (not char array) and manipulates that until you call ToString. There's no extra copying involved... but there's a lot more work maintaining lengths etc.

    Which is the more efficient solution? Well, I'd have to benchmark it to have any idea at all - but even so that's not going to tell the whole story. Are you using this in a situation with high memory pressure, where extra garbage is a real pain? How fast is your memory vs your CPU, etc?

    As ever, readability is usually king - and it doesn't get much better than Marc's answer on that front. In particular, there's no room for an off-by-one error, whereas I'd have to actually put some thought into validating the other answers. I don't like thinking. It hurts my brain, so I try not to do it very often. Using the built-in Array.Reverse sounds much better to me. (Okay, so it still fails on surrogates etc, but hey...)

    0 讨论(0)
  • 2021-01-31 07:14

    Since strings are immutable, each += statement will create a new string by copying the string in the last step, along with the single character to form a new string. Effectively, this will be an O(n2) algorithm instead of O(n).

    A faster way would be (O(n)):

    // pseudocode:
    static string ReverseString(string input) {
        char[] buf = new char[input.Length];
        for(int i = 0; i < buf.Length; ++i)
           buf[i] = input[input.Length - i - 1];
        return new string(buf);
    }
    
    0 讨论(0)
  • 2021-01-31 07:16

    x is the string to reverse.

            Stack<char> stack = new Stack<char>(x);
    
            string s = new string(stack.ToArray());
    
    0 讨论(0)
  • 2021-01-31 07:16
     static string reverseString(string text)
        {
            Char[] a = text.ToCharArray();
            string b = "";
            for (int q = a.Count() - 1; q >= 0; q--)
            {
                b = b + a[q].ToString();
            }
            return b;
        }
    
    0 讨论(0)
提交回复
热议问题