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.
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.
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)
else
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()
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;