写在前面
只是学栈的描述之类的似乎很无聊,所以我特意找了几个比较有意思的例子,一则加深对栈的理解和运用,二则,也可以开拓一下思路,此处为例二
例二、分隔符匹配问题
1、问题描述
编译器在编译一段代码时,首先进行的就是分隔符的匹配,常见的分隔符有{ } [ ] ( )/* */
2、思路
首先要知道的一件事就是:分隔符运行嵌套,而且,读入的顺序和处理的顺序相反,很显然是用栈。算法描述如下: 从左到右扫描java语句,从语句中不断的读取字符,每次读取一个字符,若发现它是左分割符,则将它压入栈;当从输入中读到一个右分割符时,则弹出栈顶 的左分隔符,并且查看它是否和右分隔符匹配,若它们不匹配,则匹配失败,程序报错;若栈顶没有左分隔符与右分隔符匹配,或者一直存在没有被匹配的左分隔符,左分隔符没有被匹配, 表现为所有的字符都读入后,栈中仍然有左分隔符,则匹配失败,程序报错;若所有的字符读入结束后,栈为空,则表示匹配成功
3、代码实现
package org.Stone6762.MStack.adopt; import java.util.Scanner; import org.Stone6762.MStack.imple.SqStack; /** * @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) { SqStack S = new SqStack(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语句"); } } }