Java 自定义Stack栈类及应用

栈是存放对象的一种特殊容器,在插入与删除对象时,这种结构遵循后进先出( Last-in-first-out,LIFO)的原则。java本身是有自带Stack类包,为了达到学习目的已经更好深入了解stack栈,自己动手自建java stack类是个很好的学习开始:

自建Java Stack 类

Stack 类:

package com.stack;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Stack Class
 * @author ganyee
 *
 */
public class Stack {
    //Define capacity constant:CAPACITY
    private static final int CAPACITY = 1024;
    //Define capacity
    private static int capacity;
    //Define the top position of stack
    //top = -1 meaning that the stack empty
    private static int top = -1;
    //Basic Object class array
    Object[] array;
    //Initialize the capacity of stack
    public Stack() {
        this.capacity = CAPACITY;
        array = new Object[capacity];
    }

    //Get the size of stack
    public int getSize(){
        if(isEmpty()){
            return 0;
        }else{
            return top + 1;
        }
    }

    //Get whether stack is empty
    public boolean isEmpty(){
        return (top < 0);
    }

    //Get the top element of stack
    public Object top() throws ExceptionStackEmpty{

        if(isEmpty()){
            throw new ExceptionStackEmpty("Stack is empty");
        }
        return array[top];

    }

    //Push element to stack
    public void push(Object element) throws ExceptionStackFull{
           if(getSize()== CAPACITY){
               throw new ExceptionStackFull("Stack is full");
           }
           array[++ top] = element;
    }

    //Pop element from stack
    public Object pop() throws ExceptionStackEmpty{
        if(isEmpty()){
            throw new ExceptionStackEmpty("Stack is empty");
        }
        return array[top --];
    }

    //Get the all elements of stack
    public String getAllElements() throws ExceptionStackEmpty{
        String[] arr = new String[top + 1];
        if(!isEmpty()){
            for(int i = 0;i < getSize();i ++){
                arr[i] = (String)array[i];
            }
        }
        return Arrays.toString(arr);
    }
}

自定义ExceptionStackEmpty异常类(关于如何自定义异常类可以看相关博客

package com.stack;

public class ExceptionStackEmpty extends Exception {

    //Constructor
    public ExceptionStackEmpty(){

    }

    //Define myself exception construct with parameters
    public ExceptionStackEmpty(String string){
        super(string);
    }
}

自定义ExceptionStackFull异常类

package com.stack;

public class ExceptionStackFull extends Exception {

    //Constructor
        public ExceptionStackFull(){

        }

        //Define myself exception construct with parameters
        public ExceptionStackFull(String string){
            super(string);
        }
}

测试类:

package com.stack;

public class StackTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Stack stack= new Stack();
        System.out.println(stack.getSize());
        System.out.println(stack.isEmpty());
        try {
            stack.push(8);
            stack.push(3);
            stack.push(4);
            stack.push(7);
            stack.push(1);
            stack.push(8);
            stack.push(3);
            stack.push(4);
            stack.push(7);
            stack.push(1);
            System.out.println(stack.getSize());
            System.out.println(stack.top());
            System.out.println(stack.getAllElements());

            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());

        } catch (ExceptionStackFull e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (ExceptionStackEmpty e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

测试结果:

0
true
10
1
[8, 3, 4, 7, 1, 8, 3, 4, 7, 1]
1
7
4
3
8
1
7
4
3
8

栈的应用:符号匹配

下面,我们将借助一个栈结构 S,通过对算术表达式自左向右的一遍扫描,检查其中的括号是

否匹配。

假设算术表达式为 X = “x0x1x2…xn-1”,其中 xi 可以是括号、常数、变量名或者算术运算符。我

们依次检查 X 中的各个符号,非括号的符号都可以忽略。若遇到左括号,则将其压入栈 S 中;若遇到右括号,则将栈顶符号弹出并与该右括号对比。如果发现某对括号不匹配,或者遇到右括号时栈为空,或者整个表达式扫描过后栈非空,都可以断定括号不匹配。

在按照以上规则扫描完所有字符后,若栈为空,则说明括号是匹配的。如果按照前面对栈的实现,每一 push()和 pop()操作都只需常数时间,因此对于长度为 n 的算术表达式,上述算法需要运行 O(n)的时间。

该算法的伪代码描述如 算法二.1 所示:

package com.stack;

public class MatchClass {

    public static boolean Match(String str) throws ExceptionStackFull, ExceptionStackEmpty{
        Stack stack = new Stack();
        str = str.replaceAll(" ","");
        char s;
        for(int i = 0;i < str.length();i ++){
            if(str.charAt(i) == ‘(‘ || str.charAt(i) == ‘{‘ || str.charAt(i) == ‘[‘)
                stack.push(str.charAt(i));
            else{
                if(stack.isEmpty())
                    return false;
                else{
                    s = str.charAt(i);
                    switch(s){
                    case ‘)‘:
                        if((Character)stack.pop() != ‘(‘)
                            return false;
                        break;
                    case ‘}‘:
                        if((Character)stack.pop() != ‘{‘)
                            return false;
                        break;
                    case ‘]‘:
                        if((Character)stack.pop() != ‘[‘)
                            return false;
                        break;
                    }
                }

            }
        }
        if(stack.isEmpty()){
            return true;
        }else{
            return false;
        }
    }
}
package com.stack;

public class ParentMatch {

    public static void main(String[] args) {

        MatchClass match = new MatchClass();
        //String str = "()({})";  //Match
        //String str = "()({}) {([()[]])}";//Match
        //String str = "([]{)";//Not match
        //String str = ")([()] {}";//Not match
        String str = "([())]{}";//Not match
        try {
            if(!match.Match(str)){
                System.out.println(str + ": Not Macth");
            }else{
                System.out.println(str + ": Macth");
            }
        } catch (ExceptionStackFull e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExceptionStackEmpty e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

测试结果:

()({}): Macth
()({}) {([()[]])}: Macth
([]{): Not Macth
)([()] {}: Not Macth
([())]{}: Not Macth

文章参考:数据结构与算法( Java 描述)邓俊辉 著

转载请注明出处,谢谢!

http://blog.csdn.net/github_27609763/article/details/46420149

时间: 2024-12-28 00:31:45

Java 自定义Stack栈类及应用的相关文章

基于数组实现Java 自定义Stack栈类及应用

栈是存放对象的一种特殊容器,在插入与删除对象时,这种结构遵循后进先出( Last-in-first-out,LIFO)的原则.java本身是有自带Stack类包,为了达到学习目的已经更好深入了解stack栈,自己动手自建java stack类是个很好的学习开始: 自建Java Stack 类 Stack 类: 1 package com.stack; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 6 /** 7 * St

java集合类——Stack栈类

今日走读代码时,遇到stack栈类,特查看java的API文档,总结如下: Stack继承Vector类. 栈的特点是后进先出. API中Stack自身的方法不多,基本跟栈的特点有关. 现附上例子,后续继续总结 /** * @作者 whs * @创建日期 2015年2月4日 * @版本 V 1.0 */ package thread.pool; import java.util.Stack; public class StackExam { public static void main(Str

基于链表实现Java 自定义Stack队列

接下来让我们看看,如何利用单链表结构来实现栈与队列.由于栈的操作只限于栈顶元素,而单链表只有对首元素才能在O(1)时间内完成插入和删除,故这里把单链表的首节点作为栈顶,其余元素依次排列.此外,为了保证getSize()方法也能够在O(1)时间内完成,还需借助一个实例变量来动态记录栈中元素的数目.具体的实现如 代码二.12 所示. Node类 Java代码见( Java 实现链表) StackLink 类: package com.list.stack; import java.util.Arra

java.util.Stack类中的peek()方法

java.util.stack类中常用的几个方法:isEmpty(),add(),remove(),contains()等各种方法都不难,但需要注意的是peek()这个方法. peek()查看栈顶的对象而不移除它. import java.util.Stack; public class MyStack1 { private Stack<Integer> stackData; private Stack<Integer> stackMin; public MyStack1(){ t

恶补java(十一)-------Stack类的使用

package com.gc.Stack; /** * java中stack的使用方法,堆栈是一种"后进先出"(LIFO)的数据结构,只能在一端进行插入(称为"压栈")或删除(称为"出栈")数据的操作. * Java中,使用java.util.Stack类的构造方法创建对象 * public class Stack extends vector * 构造方法:public Stack()创建一个空Stack * 1.public push(ite

Java Stack栈和Heap堆的区别

首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆. 在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语: 堆存储: heapstorage 堆存储分配: heapstorage allocation 堆存储管理: heap storage management 栈编址: stack addressing 栈变换:stack transformation 栈存储器:stack memory 栈单元: stack cell 接着,总结在Jav

Java的Stack类实现List接口真的是个笑话吗

今天在网上闲逛时看到了这样一个言论,说“Java的Stack类实现List接口的设计是个笑话”. 当然作者这篇文章的重点不是这个,原本我也只是一笑置之,然而看评论里居然还有人附和,说“Java那种Stack的设计作为笑话,差不多可以算公案了”,我就有点不淡定了,为什么.什么时候“作为笑话”的并且“差不多可以算公案”了呢? 因此我决定写一篇文章来谈谈这个问题. 接口是什么 狭义地讲,接口就是一个类所定义的方法(方法名.参数.返回值).一个类提供了Foo方法,其他类就可以调用它.广义上讲,接口可以理

java Stack(栈)

"Stack" 通常时指"后进后出"(LIFO)的容器,有时栈也被称为叠加栈,因为最后"压入"栈的元素,第一个"弹出"栈,经常用来类比栈的事物时装有弹簧的储存器中的自助托盘,最后装入托盘的总是最先拿出. LinkedList具有能够直接实现栈的所有功能的方法,因此可以直接将LinkedList当栈使用,不过,有时一个正真的"Stack"更能把事情讲清楚 下面时java编程思想的栈,T是泛型,类名之后加<

java自定义注解类

一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Tar