无法检查字符串是否平衡

时间:2015-10-27 21:32:30

标签: java stack

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}}。

无论出于何种原因,我的代码都没有这样做。

4 个答案:

答案 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());
    }
}