package edu.bsu.cs121.mamurphy;
import java.util.Stack;
public class Checker {
char openPara = '(';
char openBracket = '[';
char openCurly = '{';
char openArrow = '<';
char closePara = ')';
char closeBracket = ']';
char closeCurly = '}';
char closeArrow = '>';
public boolean checkString(String stringToCheck) {
Stack<Character> stack = new Stack<Character>();
for (int i = 0; i < stringToCheck.length(); i++) {
char c = stringToCheck.charAt(i);
if (c == openPara || c == openBracket || c == openCurly || c == openArrow) {
stack.push(c);
System.out.println(stack);
;
}
if (c == closePara) {
if (stack.isEmpty()) {
System.out.println("Unbalanced");
break;
} else if (stack.peek() == openPara) {
stack.pop();
} else if (stack.size() > 0) {
System.out.println("Unbalanced");
break;
}
}
if (c == closeBracket) {
if (stack.isEmpty()) {
System.out.println("Unbalanced");
break;
} else if (stack.peek() == openBracket) {
stack.pop();
} else if (stack.size() > 0) {
System.out.println("Unbalanced");
break;
}
}
if (c == closeCurly) {
if (stack.isEmpty()) {
System.out.println("Unbalanced");
break;
} else if (stack.peek() == openCurly) {
stack.pop();
} else if (stack.size() > 0) {
System.out.println("Unbalanced");
break;
}
}
if (c == closeArrow) {
if (stack.isEmpty()) {
System.out.println("Unbalanced");
break;
} else if (stack.peek() == openArrow) {
stack.pop();
} else if (stack.size() > 0) {
System.out.println("Unbalanced");
break;
}
}
}
return false;
}
}
我目前正在尝试创建一个程序,我检查字符串是否平衡。当且仅当每个开头字符:(,{,[,和&lt;具有匹配的结束字符:),},]和&gt;时,字符串是平衡的。分别。
当检查字符串时,如果找到一个开头字符,它被推入一个堆栈,它会检查是否有合适的结束字符。
如果在开头字符之前有一个结束字符,那么这自动意味着该字符串是不平衡的。此外,如果转到下一个字符后,字符串会自动失去平衡。
我尝试使用
else if (stack.size() > 0) {
System.out.println("Unbalanced");
break;
}
作为一种方式来查看堆栈中是否还有其他内容,但它仍然无法正常工作。关于该怎么做的任何建议?
例如,如果字符串输入为()<>{()
,那么程序应该像正常一样运行,直到它到达单{
,然后代码应该意识到字符串是不平衡的并输出{{ 1}}。
无论出于何种原因,我的代码都没有这样做。
答案 0 :(得分:2)
以下逻辑是有缺陷的(强调我的):
例如,如果字符串输入为
()<>{()
,那么程序应该像普通的一样运行,直到它到达单{
,然后代码应该意识到字符串不平衡,输出不平衡。
事实上,在扫描整个字符串并确定{
没有匹配}
之前,代码无法断定该字符串是不平衡的。尽管如此,完整的输入可以是()<>{()}
并且是平衡的。
要实现此目的,您需要添加一个检查,以确保在整个字符串处理完毕后堆栈为空。在您的示例中,它仍将包含{
,表示输入不平衡。
答案 1 :(得分:0)
我接受了回答。如果字符串是平衡的并且强制执行开/关顺序(即({)}
返回false),我的解决方案将返回true。我开始使用你的代码并试图减少它。
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class mamurphy {
private static final char openPara = '(';
private static final char openBracket = '[';
private static final char openCurly = '{';
private static final char openArrow = '<';
private static final char closePara = ')';
private static final char closeBracket = ']';
private static final char closeCurly = '}';
private static final char closeArrow = '>';
public static void main(String... args) {
System.out.println(checkString("{}[]()90<>"));//true
System.out.println(checkString("(((((())))"));//false
System.out.println(checkString("((())))"));//false
System.out.println(checkString(">"));//false
System.out.println(checkString("["));//false
System.out.println(checkString("{[(<>)]}"));//true
System.out.println(checkString("{[(<>)}]"));//false
System.out.println(checkString("( a(b) (c) (d(e(f)g)h) I (j<k>l)m)"));//true
}
public static boolean checkString(String stringToCheck) {
final Map<Character, Character> closeToOpenMap = new HashMap<>();
closeToOpenMap.put(closePara, openPara);
closeToOpenMap.put(closeBracket, openBracket);
closeToOpenMap.put(closeCurly, openCurly);
closeToOpenMap.put(closeArrow, openArrow);
Stack<Character> stack = new Stack<>();
final char[] stringAsChars = stringToCheck.toCharArray();
for (int i = 0; i < stringAsChars.length; i++) {
final char current = stringAsChars[i];
if (closeToOpenMap.values().contains(current)) {
stack.push(current); //found an opening char, push it!
} else if (closeToOpenMap.containsKey(current)) {
if (stack.isEmpty() || closeToOpenMap.get(current) != stack.pop()) {
return false;//found closing char without correct opening char on top of stack
}
}
}
if (!stack.isEmpty()) {
return false;//still have opening chars after consuming whole string
}
return true;
}
}
答案 2 :(得分:0)
这是另一种方法:
private static final char[] openParens = "[({<".toCharArray();
private static final char[] closeParens = "])}>".toCharArray();
public static boolean isBalanced(String expression){
Deque<Character> stack = new ArrayDeque<>();
for (char c : expression.toCharArray()){
for (int i = 0; i < openParens.length; i++){
if (openParens[i] == c){
// This is an open - put it in the stack
stack.push(c);
break;
}
if (closeParens[i] == c){
// This is a close - check the open is at the top of the stack
if (stack.poll() != openParens[i]){
return false;
}
break;
}
}
}
return stack.isEmpty();
}
它简化了具有两个相应的打开和关闭符号数组的逻辑。您也可以在一个数组中使用偶数和奇数位置执行此操作 - 即。 &#34; {}&lt;&gt;&#34;,例如:
private static final char[] symbols = "[](){}<>".toCharArray();
public static boolean isBalanced(String expression){
Deque<Character> stack = new ArrayDeque<>();
for (char c : expression.toCharArray()){
for (int i = 0; i < symbols.length; i += 2){
if (symbols[i] == c){
// This is an open - put it in the stack
stack.push(c);
break;
}
if (symbols[i + 1] == c){
// This is a close - check the open is at the top of the stack
if (stack.poll() != symbols[i]){
return false;
}
break;
}
}
}
return stack.isEmpty();
}
请注意,如果堆栈为空,则poll返回null,因此如果我们的堆栈用完,将正确地使相等比较失败。
答案 3 :(得分:0)
例如,如果字符串输入为()&lt;&gt; {(),那么程序应该像普通的一样运行,直到它到达单个{然后代码应该意识到字符串不平衡,输出不平衡。
您的示例不清楚边界是否可以像<{1}}一样嵌套。如果它们可以,那个逻辑将不起作用,因为必须消耗整个字符串以确保任何丢失的结束字符不在最后,因此,在您指示的点处,字符串不能被可靠地视为不平衡。 / p>
以下是我对你的问题的看法:
BalanceChecker类:
([{}])
主类(用于测试):
package so_q33378870;
import java.util.Stack;
public class BalanceChecker {
private final char[] opChars = "([{<".toCharArray();
private final char[] edChars = ")]}>".toCharArray();
//<editor-fold defaultstate="collapsed" desc="support functions">
public boolean isOPChar(char c) {
for (char checkChar : opChars) {
if (c == checkChar) {
return true;
}
}
return false;
}
public boolean isEDChar(char c) {
for (char checkChar : edChars) {
if (c == checkChar) {
return true;
}
}
return false;
}
//NOTE: Unused.
// public boolean isBoundaryChar(char c) {
// boolean result;
// if (result = isOPChar(c) == false) {
// return isEDChar(c);
// } else {
// return result;
// }
// }
public char getOpCharFor(char c) {
for (int i = 0; i < edChars.length; i++) {
if (c == edChars[i]) {
return opChars[i];
}
}
throw new IllegalArgumentException("The character (" + c + ") received is not recognized as a closing boundary character.");
}
//</editor-fold>
public boolean isBalanced(char[] charsToCheck) {
Stack<Character> checkStack = new Stack<>();
for (int i = 0; i < charsToCheck.length; i++) {
if (isOPChar(charsToCheck[i])) {
//beginning char found. Add to top of stack.
checkStack.push(charsToCheck[i]);
} else if (isEDChar(charsToCheck[i])) {
if (checkStack.isEmpty()) {
//ending char found without beginning chars on the stack. UNBALANCED.
return false;
} else if (getOpCharFor(charsToCheck[i]) == checkStack.peek()) {
//ending char found matches last beginning char on the stack. Pop and continue.
checkStack.pop();
} else {
//ending char found, but doesn't match last beginning char on the stack. UNBALANCED.
return false;
}
}
}
//the string is balanced if and only if the stack is empty at the end.
return checkStack.empty();
}
public boolean isBalanced(String stringToCheck) {
return isBalanced(stringToCheck.toCharArray());
}
}