我过去曾经写过使用堆栈来检查平衡方程的软件,但是现在我被要求递归编写一个类似的算法来检查正确嵌套的括号和括号。
很好的例子:()[]()([]()[]) 错误的例子:((]([)]
很好的例子:()[]()([]()[])
错误的例子:((]([)]
假设我的函数名为:isBalanced。
每个遍都应该评估一个较小的子字符串(直到剩下2个基本情况)?或者,我应该始终评估完整字符串并将索引向内移动吗?
有很多方法可以做到这一点,但是最简单的算法是简单地从左到右处理,将堆栈作为参数传递
FUNCTION isBalanced(String input, String stack) : boolean IF isEmpty(input) RETURN isEmpty(stack) ELSE IF isOpen(firstChar(input)) RETURN isBalanced(allButFirst(input), stack + firstChar(input)) ELSE IF isClose(firstChar(input)) RETURN NOT isEmpty(stack) AND isMatching(firstChar(input), lastChar(stack)) AND isBalanced(allButFirst(input), allButLast(stack)) ELSE ERROR "Invalid character"
这里是用Java实现的。请注意,为了方便起见,我现在已对其进行了切换,以便堆栈推入字符串的 前面 而不是 后面 。我还对其进行了修改,以使其仅跳过非括号符号,而不是将其报告为错误。
static String open = "([<{"; static String close = ")]>}"; static boolean isOpen(char ch) { return open.indexOf(ch) != -1; } static boolean isClose(char ch) { return close.indexOf(ch) != -1; } static boolean isMatching(char chOpen, char chClose) { return open.indexOf(chOpen) == close.indexOf(chClose); } static boolean isBalanced(String input, String stack) { return input.isEmpty() ? stack.isEmpty() : isOpen(input.charAt(0)) ? isBalanced(input.substring(1), input.charAt(0) + stack) : isClose(input.charAt(0)) ? !stack.isEmpty() && isMatching(stack.charAt(0), input.charAt(0)) && isBalanced(input.substring(1), stack.substring(1)) : isBalanced(input.substring(1), stack); }
测试线束:
String[] tests = { "()[]<>{}", "(<", "]}", "()<", "(][)", "{(X)[XY]}", }; for (String s : tests) { System.out.println(s + " = " + isBalanced(s, "")); }
输出:
()[]<>{} = true (< = false ]} = false ()< = false (][) = false {(X)[XY]} = true