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 }

//获得栈的具体使用操作后,下面使用堆栈完成对括号匹配算法的使用:

 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 }
时间: 2024-08-17 19:37:54

Java堆栈的应用1----------堆栈的自定义实现以及括号匹配算法的Java实现的相关文章

Java知识点归总一之堆栈

Java栈与堆 (一天一个知识点2014-07-28) ----对这两个概念的不明好久,终于找到一篇好文,拿来共享 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器.但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性.另外,栈数据可以共 享,详见第3点.堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java

浅谈C/C++堆栈指引——C/C++堆栈

C/C++堆栈指引 Binhua Liu 前言 我们经常会讨论这样的问题:什么时候数据存储在飞鸽传书堆栈(Stack)中,什么时候数据存储在堆(Heap)中.我们知道,局部变量是存储在堆栈中的:debug时,查看堆栈可以知道函数的调用顺序:函数调用时传递参数,事实上是把参数压入堆栈,听起来,堆栈象一个大杂烩.那么,堆栈(Stack)到底是如何工作的呢? 本文将详解C/C++堆栈的工作机制.阅读时请注意以下几点: 1)本文讨论的语言是 Visual C/C++,由于高级语言的堆栈工作机制大致相同,

堆栈二链表实现堆栈

用链表来实现堆栈的优点是随时可以动态改变链表的长度,能够有效利用内存资源,缺点就是设计的算法比较复杂 class Node: #堆栈链结节点的声明 def __init__(self): self.data=0 #堆栈数据的声明 self.next=None #堆栈中用来指向下一个节点 top=None 判断链表是否为空 def isEmpty(): global top if(top==None): return 1 else: return 0 将指定的数据压入堆栈 #将指定的数据压入堆栈

自定义多列排序:C++/Java实现

前言: 有些时候,我们在编程中会遇到多列排序的需求.假如在execle,这事儿就太easy了.不过没办法,现在就需要你用Java或者C++实现这样一个功能! 比如将下表无序的数据通过重排之后按照以下规则显示结果: 1.第二列从大到小排列 2.若第二列相等,则第一列按照从大到小排序 排序前 排序后 2 53 22 111 7521 10132 2120 5913 21 21 10111 7520 5913 2132 212 53 22 1 -----------------------------

JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配

Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要在运行时动态分配内存,存取速度较慢. 栈的优势是

Java千百问_01基本概念(001)_什么是Java

点击进入_更多_Java千百问 1.什么是Java Java是一种开发语言(核心特点:跨平台,面向对象,名称由来看这里:J2EE里面的2是什么意思),对于开发者来讲,Java基本等于Jdk. Jdk的版本介绍看这里:[Java都有那些版本][3] 开发人员一般通过IDE(Eclipse.NetBeans.JBuilder等)编写.编译Java代码(在远古没有IDE的时代,都是用文本编辑器编写,使用javac编译),在这个过程中,会使用到Jdk与第三方Jar包(Jar包即一组编译后的类打成的压缩包

转载——Java与WCF交互(一)补充:用WSImport生成WSDL的Java客户端代码

在<Java与WCF交互(一):Java客户端调用WCF服务>一文中,我描述了用axis2的一个Eclipse控件生成WCF的Java客户端代理类,后来有朋友建议用Xfire.CXF,一直没有尝试,今天有朋友指出JDK6可以用java自带的一个WSImport工具,试了下,果然很爽,这是一个exe文件,位于%JAVA_HOME%\bin下,它的官方使用说明,见:http://download-llnw.oracle.com/javase/6/docs/technotes/tools/share

A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No Java virtual machine was found after searching the following locations: /usr/local/eclipse/

linux系统下jdk是已经安装好的情况之下软件出现 A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No Java virtual machine was found after searching the following locations: /usr/local/eclipse/jre/bin/java java in yo

Ubuntu Eclipse启动时报错:A Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No java virtual machine was found after searching the following locations:

此问题起于我在Ubuntu1004上装了两个版本的eclipse:Galieo+helios:卸载前者后出现启动不了eclipse的问题:在网上找了下,可以按如下过程进行解决: Eclipse 3.6 在 Ubuntu 10.04 下会出现一个很奇怪的现象,我没有经过测试,无法确定是Ubuntu 10.04 还是 JDK 还是 Eclipse本身造成的. 这个现象是: 可以在终端顺利启动Eclipse,但是鼠标双击,或者用起动器启动就会出现如下的内容: A Java RunTime Enviro