接下篇:http://www.cnblogs.com/fuck1/p/5995857.html
堆栈的应用1:括号匹配算法
括号匹配问题
假设算术表达式中包含圆括号,方括号,和花括号三种类型。使用栈数据结构编写一个算法判断表达式中括号是否正确匹配,并设计一个主函数测试。
比如:{a+[b+(c*a)/(d-e)]} 正确
([a+b)-(c*e)]+{a+b} 错误
对于表达式中的括号是否匹配,不能仅仅通过统计左括号'('出现的次数和右括号')'出现的次数是否相等来实现,“a*)b+c(”这样的表达式中的括号显然是不匹配的。检验括号是否匹配最常见的方法是借助于栈这种数据结构,从左到右逐个字符扫描表达式,碰到左括号"("则压入栈中(push),碰到右括号")"则弹出栈顶元素(pop)如果栈为空,则匹配失败。字符串扫描完成后,如果栈为空,则匹配成功,否则匹配失败。
//-------------------------------------------------------------在这里虽然Java给出了Stack的类但是还是自定义
//下面是一个stack接口的定义
1 //栈接口 2 public interface Stack { 3 4 // 入栈 5 public void push(Object obj) throws Exception; 6 7 // 出栈 8 public Object pop() throws Exception; 9 10 // 获得栈顶元素 11 public Object getTop() throws Exception; 12 13 // 判断栈是否为空 14 public boolean isEmpty(); 15 }
//顺序栈的具体实现,通过数组实现
1 //顺序栈 2 3 public class SequenceStack implements Stack { 4 5 Object[] stack; // 对象数组 6 final int defaultSize = 10; // 默认长度 7 int top;// 栈顶位置 8 int maxSize;// 最大长度 9 10 public SequenceStack() { 11 // 默认方法初始化 12 init(defaultSize); 13 } 14 15 // 显示调用方法初始化 16 public SequenceStack(int size) { 17 // 根据用户传入的参数进行初始化 18 init(size); 19 } 20 21 // 初始化方法 22 private void init(int size) { 23 this.maxSize = size; 24 top = 0; 25 stack = new Object[size]; 26 } 27 28 // 入栈操作 29 @Override 30 public void push(Object obj) throws Exception { 31 // TODO Auto-generated method stub 32 // 判断栈是否已满 33 if (top == maxSize) { 34 throw new Exception("堆栈已满"); 35 } 36 // 入栈 37 stack[top] = obj; 38 top++; 39 } 40 41 // 出栈 42 @Override 43 public Object pop() throws Exception { 44 // TODO Auto-generated method stub 45 // 判断栈是否为空 46 if (isEmpty()) { 47 throw new Exception("堆栈为空!"); 48 } 49 // 因为在入栈之后默认将top值进行了++所以导致不指示当前位置 50 top--; 51 return stack[top]; 52 } 53 54 // 获得栈顶元素 55 @Override 56 public Object getTop() throws Exception { 57 // TODO Auto-generated method stub 58 if (isEmpty()) { 59 throw new Exception("堆栈为空!!"); 60 } 61 // 单纯获得栈顶元素 62 return stack[top - 1]; 63 } 64 65 @Override 66 public boolean isEmpty() { 67 // TODO Auto-generated method stub 68 return top == 0; 69 } 70 71 }
//获得栈的具体使用操作后,下面使用堆栈完成对括号匹配算法的使用:
1 import java.util.Scanner; 2 3 //平衡符号算好,检查算数式的括号是否是正确的,小括号,中括号,大括号 4 public class Test { 5 public static void main(String[] args) throws Exception { 6 String str = "{a + [b + ( c * a ) / ( d * e)]}"; 7 String str2 = "{a+(a*B)+[a-1] + }"; 8 9 signCheck(str2); 10 } 11 12 // 字符串检查 13 public static void signCheck(String str) throws Exception { 14 SequenceStack stack = new SequenceStack(); 15 String[] arr = expToStringArray(str); 16 for (int i = 0; i < arr.length; i++) { 17 // 如果数组中有这三种左括号元素那么直接进行入栈操作 18 if (arr[i].equals("(") || arr[i].equals("[") || arr[i].equals("{")) { 19 stack.push(arr[i]); 20 } 21 22 else if (arr[i].equals(")") && !stack.isEmpty() 23 && stack.getTop().equals("(")) { 24 // 上面的if判断主要是当我们遇到右括号时,发现当前位于栈顶的是左括号,那么此时可以出栈了 25 stack.pop(); 26 } 27 28 else if (arr[i].equals(")") && !stack.isEmpty() 29 && !stack.getTop().equals("(")) { 30 31 System.out.println("左右括号匹配次序不成功"); 32 return; 33 } 34 // 遇到中括号时 35 else if (arr[i].equals("]") && !stack.isEmpty() 36 && stack.getTop().equals("[")) { 37 // 上面的if判断主要是当我们遇到右括号时,发现当前位于栈顶的是左括号,那么此时可以出栈了 38 stack.pop(); 39 } 40 41 else if (arr[i].equals("]") && !stack.isEmpty() 42 && !stack.getTop().equals("[")) { 43 44 System.out.println("左右括号匹配次序不成功"); 45 return; 46 } 47 48 // 大括号匹配 49 else if (arr[i].equals("}") && !stack.isEmpty() 50 && stack.getTop().equals("{")) { 51 // 上面的if判断主要是当我们遇到右括号时,发现当前位于栈顶的是左括号,那么此时可以出栈了 52 stack.pop(); 53 } 54 55 else if (arr[i].equals("}") && !stack.isEmpty() 56 && !stack.getTop().equals("{")) { 57 58 System.out.println("左右括号匹配次序不成功"); 59 return; 60 } 61 62 // 右括号多于左括号的情况 63 else if (arr[i].equals(")") || arr[i].equals("]") 64 || arr[i].equals("}") && stack.isEmpty()) { 65 System.out.println("右括号多于左括号"); 66 return; 67 } 68 } 69 // 经历完一趟循环后如果堆栈不为空,那么左括号就多了 70 if (!stack.isEmpty()) { 71 System.out.println("左括号多于右括号"); 72 } else { 73 System.out.println("匹配正确"); 74 } 75 76 } 77 78 // 字符串转为字符串数组 79 public static String[] expToStringArray(String exp) { 80 // 字符串数组长度 81 int n = exp.length(); 82 String[] arr = new String[n]; 83 for (int i = 0; i < n; i++) { 84 arr[i] = exp.substring(i, i + 1); 85 } 86 87 return arr; 88 } 89 }