Interview question

Interview question

  • Comments 47

Here’s a nice simple interview question:

In a given .NET string, assume there are line breaks in standard \r\n form (basically Environment.NewLine).

Write a method that inserts a space between two consecutive line breaks to separate any two line breaks from each other.

Also, anyone venture a guess what is a practical application for such a method?

  • string.Replace("\r\n\r\n", "\r\n \r\n");

  • Good one Robert, I like it, its simpler than mine.

    string insertSpaceBetweenLineBreaks(string input)

    {

       return Regex.Replace(input, "(\r\n)(\\1)", "$1 $2");

    }

  • Beaten to it. I was thinking exactly the same as Robert.

  • I'm afraid it's not that easy. What about \r\n\r\n\r\n ? :)

  • As Ben mentionned, you need to take care of more than 2 consecutive breaks. I think it is necessary to iterate through the chars and create a new string as you go (which isn't an optimum solution):

    string text = "hello \r\n\r\n\r\n world!";

    string textResult = "";

    char[] caFromText = text.ToCharArray();

    for (int i = 0; i < caFromText.Length; ++i)

    {

    textResult += caFromText[i];

    if ((int)caFromText[i] == CARRIAGE_RETURN)

    {

     // check if not reaching the end of the array

     if (i + 3 < caFromText.Length)

     {

      if ((int)caFromText[i + 1] == NEW_LINE

      && (int)caFromText[i + 2] == CARRIAGE_RETURN

      && (int)caFromText[i + 3] == NEW_LINE)

      {

       // two consecutive breaks where detected

       textResult += "\n ";

       // jump to the next break

       ++i;

      }

     }

    }

    }

  • Hmmm, this version works via loop but I'd like to see a recursive version.

    This version uses a dash instead of space so its easy to see result.

    string insertSpaceBetweenLineBreaks(string input)

    {

       while (Regex.Match(input, "(\r\n)(\\1)").Success)

       {

           input = Regex.Replace(input, "(\r\n)(\\1)", "$1-$1");

       }

       return input;

    }

    The test string I used was "A\r\nB\r\n\r\nC\r\n\r\n\r\nD\r\n\r\n\r\n\r\nE".

    This is the result

    A

    B

    -

    C

    -

    -

    D

    -

    -

    -

    E

  • Recursive version, same result as previous while loop version.

    string insertSpaceBetweenLineBreaksRec(string input)

    {

       if (!Regex.Match(input, "(\r\n)(\\1)").Success)

       {

           return input;

       }

       else

       {

           input = Regex.Replace(input, "(\r\n)(\\1)", "$1-$1");

           return insertSpaceBetweenLineBreaksRec(input);

       }

    }

  • Ben is right, Robert's original way doesn't work. Longer solutions will work, yes, but what about performance?

    I'm still not happy :) Any other ideas?

  • BTW it is amazing how the comments reflect my own train of thought as I was solving it.

  • In terms of why you might want this - SMTP?

  • Jon - pretty close. Not SMTP, but another web protocol, yes. Thanks for not revealing the answer just yet ;)

  • Sorry, not protocol - I should say "markup language"

  • Slightly faster :

    public static string Method3(string input)

           {

               int startIndex = 0;

               var sb = new StringBuilder(input.Length * 2);

               while (true)

               {

                   int index = input.IndexOf("\r\n", startIndex);

                   if (index == -1)

                   {

                       break;

                   }

                   int length = index - startIndex;

                   sb.Append(input.Substring(startIndex, length));

                   if (length == 1)

                   {

                       sb.Append("-");

                   }

                   startIndex = index + 1;

               }

               return sb.ToString();

           }

    Not much of a difference though.

  • straigtforward solution

    let insertSpaces (s : string) =

       let rec loop (i : int) acc =

           let newIndex = s.IndexOf("\r\n\r\n", i)

           if newIndex = -1 then acc + s.Substring(i)

           else loop (newIndex + 2) (acc + s.Substring(i, newIndex - i) + "\r\n ")

       loop 0 ""

    or

    let insertSpaces2 (s : string) =

       let checkCrlf i =

           if i < s.Length - 1 then s.[i] = '\r' && s.[i+1] = '\n'

           else false

       let rec loop i crlf (acc : System.Text.StringBuilder) =

           if i >= s.Length then acc.ToString()

           else

               let found = checkCrlf i

               match found, crlf with

               | true, true -> loop i false (acc.Append(' '))

               | true, false -> loop (i + 2) true (acc.Append("\r\n"))

               | false, _ -> loop (i + 1) false (acc.Append(s.[i]))

       loop 0 false (new System.Text.StringBuilder())

  • Here's my take at it :

           public static string InsertSpacesBetweenLineBreaks(string s)

           {

               StringBuilder sb = new StringBuilder();

               bool prevCrLf = false;

               char prev = '\0';

               foreach (char c in s)

               {

                   if (c == '\n' && prev == '\r')

                   {

                       if (prevCrLf) sb.Append(' ');

                       prevCrLf = true;

                   }

                   else if (c != '\r')

                   {

                       prevCrLf = false;

                   }

                   sb.Append(c);

                   prev = c;

               }

               return sb.ToString();

           }

Page 1 of 4 (47 items) 1234
Leave a Comment
  • Please add 6 and 3 and type the answer here:
  • Post