栈的应用—分隔符匹配

Posted 鹏达君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈的应用—分隔符匹配相关的知识,希望对你有一定的参考价值。

例二、分隔符匹配问题

 

1、问题描述

 
编译器在编译一段代码时,首先进行的就是分隔符的匹配,常见的分隔符有{   } [   ]  (   )/*  */
 

2、思路

 
首先要知道的一件事就是:分隔符运行嵌套,而且,读入的顺序和处理的顺序相反,很显然是用栈。
算法描述如下: 从左到右扫描java语句,从语句中不断的读取字符,每次读取一个字符,若发现它是左分割符,则将它压入栈;
当从输入中读到一个右分割符时,则弹出栈顶 的左分隔符,并且查看它是否和右分隔符匹配,若它们不匹配,则匹配失败,程序报错; 
若栈顶没有左分隔符与右分隔符匹配,或者一直存在没有被匹配的左分隔符,左分隔符没有被匹配,表现为所有的字符都读入后,栈中仍然有左分隔符,则匹配失败,程序报错; 
若所有的字符读入结束后,栈为空,则表示匹配成功
 

3、代码实现

 package org.Stone6762.MStack.adopt;  
  
import java.util.Scanner;  
  
import org.Stone6762.MStack.imple.SeqStack;  
  
/** 
 * @author_Stone6762 
 */  
public class MatchTest {  
  
    /** 
     * @LEFT记录分隔符为“左”分隔符 
     */  
    private final int LEFT = 0;  
  
    /** 
     * @RIGHT记录分隔符为“右”分隔符 
     */  
    private final int RIGHT = 1;  
  
    /** 
     * @OTHER记录其他字符 
     */  
    private final int OTHER = 2;  
  
    /** 
     * @MAXSIZE栈的大小_也就是整个程序中的左分隔符的个数的最大值 
     */  
    private final int MAXSIZE = 100;  
  
    /** 
     * @Describe_判断分隔符的类型_左_右_非法 
     * @param str 
     * @return 
     */  
    public int verifyFlag(String str) {  
        if ("(".equals(str) || "[".equals(str) || "{".equals(str)  
                || "/*".equals(str)) {  
            return LEFT;  
        } else if (")".equals(str) || "]".equals(str) || "}".equals(str)  
                || "*/".equals(str)) {  
            return RIGHT;  
        } else {  
            return OTHER;  
  
        }  
  
    }  
  
    /** 
     * @Describe_判断左分隔符str1和右分隔符str2是否匹配 
     * @param str1 
     * @param str2 
     * @return 
     */  
    public boolean matches(String str1, String str2) {  
        if (("(".equals(str1) && ")".equals(str2))  
                || ("{".equals(str1) && "}".equals(str2))  
                || ("[".equals(str1) && "]".equals(str2))  
                || ("/*".equals(str1) && "*/".equals(str2))) {  
            return true;  
        } else {  
            return false;  
        }  
    }  
  
    /** 
     * @Describe_判断是否匹配 
     * @param str 
     * @return 
     * @throws Exception 
     */  
    public boolean isLegal(String str) throws Exception {  
        if (!"".equals(str) && str != null) {  
            SeqStack S = new SeqStack(MAXSIZE);  
            int length = str.length();  
            for (int i = 0; i < length; i++) {  
                // 取出元素  
                char c = str.charAt(i);  
                String t = String.valueOf(c);  
  
                // 对 分隔符/**/特别处理  
                if (i != length) {  
                    if ((‘/‘ == c && ‘*‘ == str.charAt(i + 1))  
                            || (‘*‘ == c && ‘/‘ == str.charAt(i + 1))) {  
                        t = t.concat(String.valueOf(str.charAt(i + 1)));  
                        i++;  
                    }  
                }  
                // 如果是左分隔符,入栈,如果是右分隔符,出栈,看是否匹配,如果不匹配,报错  
                if (LEFT == verifyFlag(t)) {  
                    S.push(t);  
                } else if (RIGHT == verifyFlag(t)) {  
                    if (S.isEmpty()) {  
                        throw new Exception("错误:   java语法不合法,缺少左分隔符");  
                    } else if (!matches(S.pop().toString(), t)) {  
                        throw new Exception("错误:   java语法不合法,左右分隔符不匹配");  
                    }  
                }  
            }  
            // 对整个语句遍历后,如果栈非空,证明栈中还有未被匹配的左分隔符,此时是错误的  
            if (!S.isEmpty()) {  
                throw new Exception("错误: java语句不合法,缺少右分隔符");  
            } else {  
                return true;  
            }  
        } else {  
            throw new Exception("错误:Java语句为空 ! ");  
        }  
    }  
  
    public static void main(String[] args) throws Exception {  
        MatchTest m = new MatchTest();  
        Scanner scan = new Scanner(技术分享System.in);  
        System.out.println("请输入 想要判断 java语句");  
        while (scan.hasNext()) {  
            if (m.isLegal(scan.nextLine())) {  
                System.out.println("Java语句正确");  
            } else {  
                System.out.println("错误:Java语句不合法");  
            }  
            System.out.println();  
            System.out.println("请输入 想要判断 java语句");  
        }  
    }  

以上是关于栈的应用—分隔符匹配的主要内容,如果未能解决你的问题,请参考以下文章

栈的应用之括号匹配的检验

栈的应用(括号匹配算法实战)

栈的应用 - 就近匹配

栈的应用-判断括号匹配

王道3.3 栈的应用

数据结构 栈的实例应用,括号匹配