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 }

 

posted @ 2016-10-25 11:21  我所向往的美好  阅读(2522)  评论(0编辑  收藏  举报