假设一个算术表达式中包含圆括号()、方括号[]和花括号{}三类括号,要求判断表达式中括号是否正确匹配配对。
分析:括号匹配符号后到的括号要最先被匹配,所以满足栈“后进先出”的特点。
括号匹配共有四种情况:(1)左右括号配对次序不正确,即存在类似“(]”这种情况;(2)右括号多于左括号;(3)左括号多于右括号;(4)匹配正确。
综上:我们可以存储表达式的字符串并按顺序扫描,进行匹配。顺序栈和链式堆栈都可以;
下面看代码:(不再构造栈类,上篇有)
package StackAndQueue;
/**
* @author sun
* 创建时间:2017年3月30日下午2:52:31
*/
public class BraceMatch {
//遍历字符数组并利用进栈出栈匹配括号
static void expIsCorrect(String[] exp,int n)throws Exception{
SeqStack myStack = new SeqStack();
//LinStack myStack = new LinStack(); //也可以用链式堆栈
for(int i=0;i<n;i++){//如果是左括号就入栈
if((exp[i].equals(new String("(")))
|| (exp[i].equals(new String("[")))
|| (exp[i].equals(new String("{"))))
myStack.push(exp[i]);
//如果是右括号)并且和栈顶(匹配,出栈
else if((exp[i].equals(new String(")"))) && myStack.notEmpty()
&& myStack.getTop().equals(new String("(")))
myStack.pop();
//遍历的右括号)和栈顶不匹配,说明公式错误,结束遍历
else if((exp[i].equals(new String(")"))) && myStack.notEmpty()
&& !myStack.getTop().equals(new String("("))){
System.out.println("左右括号匹配次序不正确!");
return;
}
//如果是右括号]并且和栈顶[匹配,出栈
else if((exp[i].equals(new String("]"))) && myStack.notEmpty()
&& myStack.getTop().equals(new String("[")))
myStack.pop();
//遍历的右括号]和栈顶不匹配,说明公式错误,结束遍历
else if((exp[i].equals(new String("]"))) && myStack.notEmpty()
&& !myStack.getTop().equals(new String("["))){
System.out.println("左右括号匹配次序不正确!");
return;
}
//如果是右括号}并且和栈顶{匹配,出栈
else if((exp[i].equals(new String("}"))) && myStack.notEmpty()
&& myStack.getTop().equals(new String("{")))
myStack.pop();
//遍历的右括号}和栈顶不匹配,说明公式错误,结束遍历
else if((exp[i].equals(new String("}"))) && myStack.notEmpty()
&& !myStack.getTop().equals(new String("{"))){
System.out.println("左右括号匹配次序不正确!");
return;
}
//如果栈已空,但还存在右括号,说明右括号多了
else if((exp[i].equals(new String(")")))
|| (exp[i].equals(new String("]")))
|| (exp[i].equals(new String("}")))
&& !myStack.notEmpty()){
System.out.println("右括号多余左括号!");
return;
}
}
//遍历完成后栈内还有元素,说明左括号多了
if(myStack.notEmpty())
System.out.println("左括号多余右括号!");
else
System.out.println("括号匹配正确!");
}
private static String[] strToString(String str){//把字符串转换为String类型数组
//为什么不转换为字符数组char[]呢?
//因为只有String类型的数据才具有可比性,也就是能用equals
int n = str.length();
String[] a = new String[n];
for(int i=0;i<n;i++){
a[i] = str.substring(i,i+1);//取子串含头不含尾,故可以取出i位置的字符并返回字符串类型
}
return a;
}
public static void main(String[] args) {
String str;
int n;
try{
str = "(())abc{[}(){";//左右括号匹配次序不正确
n = str.length();
String[] a = strToString(str);
expIsCorrect(a,n);
str = "(()))abc{[]}";//右括号多余左括号
n = str.length();
String[] b = strToString(str);
expIsCorrect(b,n);
str = "(()()abc{[]}";//左括号多余右括号
n = str.length();
String[] c = strToString(str);
expIsCorrect(c,n);
str = "(())abc{[]}";//括号匹配正确!
n = str.length();
String[] d = strToString(str);
expIsCorrect(d,n);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
/*
左右括号匹配次序不正确!
右括号多余左括号!
左括号多余右括号!
括号匹配正确!
*/