接下篇: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 }