[Java数据结构]使用Stack检查表达式中左右括号是否匹配

Stack是一种先进后出的数据结构后,这个特点决定了它在递归向下的场景中有独到的功效。

以下程序展示了它在检查表达式中括号匹配的有效性:

程序:

package com.heyang.util;

import java.util.Collections;
import java.util.Stack;

class Bracket{
    char type;
    int idx;
    
    public Bracket(char type,int idx) {
        this.type=type;
        this.idx=idx;
    }
}

// Used to check if the brackets in a expression is balanced
public class BracketChecker {
    private String errMsg;
    
    public String getErrMsg() {
        return errMsg;
    }
    
    public boolean isBalanced(String expression) {
        boolean retval=false;
        
        try {
            retval=checkBalanced(expression);
        }catch(Exception ex) {
            errMsg=ex.getMessage();
        }
        
        return retval;
    }
    
    private boolean checkBalanced(String expression) throws Exception{
        int length=expression.length();
        Stack<Bracket> stack=new Stack<Bracket>();
        
        for(int i=0;i<length;i++){
            char ch=expression.charAt(i);
            
            if(ch=='{' || ch=='[' || ch=='('){
                stack.push(new Bracket(ch,i));
            }else if(ch==')' || ch==']' || ch=='}'){
                if(stack.isEmpty()) {
                    throw new Exception(buildErrorMsg(expression,ch,i));
                }else {
                    Bracket popedBracket=stack.pop();
                    
                    if( (ch==')' && popedBracket.type !='(') || 
                        (ch==']' && popedBracket.type !='[') || 
                        (ch=='}' && popedBracket.type !='{') ){
                        throw new Exception(buildErrorMsg(expression,popedBracket.type,popedBracket.idx));
                        //throw new Exception(buildErrorMsg(expression,ch,i));
                    }
                }
            }
        }
        
        Bracket popedBracket=null;
        while(stack.isEmpty()==false) {
            popedBracket=stack.pop();
        }
        if(popedBracket!=null) {
            throw new Exception(buildErrorMsg(expression,popedBracket.type,popedBracket.idx));
        }
        
        return true;
    }
    
    // build error message
    private String buildErrorMsg(String expression,char ch,int idx) {
        StringBuilder sb=new StringBuilder();
        sb.append(""+expression+"\n");
        sb.append(createRepeatedStr(" ",idx)+"^");
        sb.append(" This bracket '"+ch+"' has not matched bracket!\n");
        
        return sb.toString();
    }
    
    // Repeat seed with n times
    private static String createRepeatedStr(String seed,int n) {
        return String.join("", Collections.nCopies(n, seed));
    }
    
    // Entry point
    public static void main(String[] args) {
        BracketChecker bbc=new BracketChecker();
        
        String[] arr= {"123)456","5+2*(3+3)","{[(2+4)*8]/6}","[()]}","{[(]}","{[](","((((())))))","((([((())))))","[[[[[]]]]]","{[(((((()))))))]}"};
        
        int index=0;
        for(String expression:arr) {
            index++;
            
            boolean balanced=bbc.isBalanced(expression);
            if(!balanced) {
                System.out.println("#"+index+"\n"+bbc.getErrMsg());
            }
        }
    }
}

输出:

#1
123)456
   ^ This bracket ')' has not matched bracket!

#4
[()]}
    ^ This bracket '}' has not matched bracket!

#5
{[(]}
  ^ This bracket '(' has not matched bracket!

#6
{[](
^ This bracket '{' has not matched bracket!

#7
((((())))))
          ^ This bracket ')' has not matched bracket!

#8
((([((())))))
   ^ This bracket '[' has not matched bracket!

#10
{[(((((()))))))]}
 ^ This bracket '[' has not matched bracket!

--2020年5月23日--

posted @ 2019-12-24 09:51  逆火狂飙  阅读(459)  评论(1编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东