The issue is not in the Java->C# translation, but in the fact that you translated a string to a StringBuilder. When you call
str.Append("(");
You are appending "(" to the current string builder instance (str
), and when you do
CombiParentheses(open - 1, close + 1, str.Append("("));
passing that instance itself on your method call, not a new instance.
An easy way to see the problem: suppose you're calling
CombiParentheses(2, 0, str);
When the second output string is written, the call stack will have been
CombiParentheses(2, 0, str):
CombiParentheses(1, 1, str.Append("(")):
CombiParentheses(0, 2, str.Append("(")):
CombiParentheses(0, 1, str.Append(")")):
CombiParentheses(0, 0, str.Append(")")); // StringBuilder was reset here!
CombiParentheses(1, 0, str.Append(")")):
CombiParentheses(0, 1, str.Append("(")):
CombiParentheses(0, 0, str.Append(")"));
Since you're using a single string builder instance, and you cleared it right before the call stack went into
CombiParentheses(1, 0, str.Append(")"));
The next output will match the output of that call, as if str had no characters on it yet, not the output you're expecting (which would be as if str still had a "("
on it).
If you used a string instead, when you do (string + ")")
, the result is a new string, not the same object that you modified, so the problem doesn't arise, when you get back to a CombiParentheses
call made earlier in the recursive execution you still have the original string that CombiParentheses
call received.
You can use this do see it in runtime:
public static void CombiParentheses(int open, int close, StringBuilder str)
{
Console.WriteLine("open: {0}; close: {1}; str: {2}", open, close, str.ToString());
if (open == 0 && close == 0)
{
Console.WriteLine(str.ToString());
str.Clear();
}
if (open > 0)
{
CombiParentheses(open - 1, close + 1, str.Append("("));
}
if (close > 0)
{
CombiParentheses(open, close - 1, str.Append(")"));
}
}
public static void CombiParenthesesFixed(int open, int close, string str)
{
Console.WriteLine("open: {0}; close: {1}; str: {2}", open, close, str);
if (open == 0 && close == 0)
{
Console.WriteLine(str);
}
if (open > 0)
{
CombiParentheses(open - 1, close + 1, str + "(");
}
if (close > 0)
{
CombiParentheses(open, close - 1, str + ")");
}
}