Java堆棧的應用1----------堆棧的自定義實現以及括號匹配算法的Java實現


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

//順序棧的具體實現,通過數組實現

 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 }
View Code

//獲得棧的具體使用操作后,下面使用堆棧完成對括號匹配算法的使用:

 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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM