我在C#中实现了polygenelubricants的java代码(Valid Permutation of Parenthesis)。
我的C#代码:
public static void CombiParentheses(int open, int close, StringBuilder str)
{
if (open == 0 && close == 0)
{
Console.WriteLine(str.ToString());
str.Clear();
}
if (open > 0) //when you open a new parentheses, then you have to close one parentheses to balance it out.
{
CombiParentheses(open - 1, close + 1, str.Append("{"));
}
if (close > 0)
{
CombiParentheses(open , close - 1, str.Append("}"));
}
}
但是我得到了错误的结果:
CombiParentheses(3, 0, tempString2);
{{{}}}
}{}}
}{}
}{{}}
}{}
导致C#和Java实现之间存在这种差异的原因是什么?
答案 0 :(得分:2)
问题不在Java-> C#转换中,而在于您将字符串转换为StringBuilder。当你打电话
str.Append("(");
您正在追加"("到当前字符串构建器实例(str
),并在您执行时
CombiParentheses(open - 1, close + 1, str.Append("("));
在方法调用中传递该实例本身,而不是新实例。
查看问题的简单方法:假设您正在调用
CombiParentheses(2, 0, str);
写入第二个输出字符串时,调用堆栈将是
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(")"));
由于您正在使用单个字符串构建器实例,并且在调用堆栈进入之前就已将其清除
CombiParentheses(1, 0, str.Append(")"));
下一个输出将匹配该调用的输出,好像str上没有字符,而不是您期望的输出(这就好像str仍然有一个"("
就可以了。)
如果您使用了字符串,那么当您执行(string + ")")
时,结果是新字符串,而不是您修改的同一个对象,因此问题不会出现,当您回到先前在递归执行中进行的CombiParentheses
调用时,您仍然拥有CombiParentheses
调用的原始字符串。
你可以使用它在运行时看到它:
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 + ")");
}
}