基于动态数组实现栈(利用栈去实现括弧匹配)

Posted zhixiangshu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于动态数组实现栈(利用栈去实现括弧匹配)相关的知识,希望对你有一定的参考价值。

(希望我所描述的,给你带来收获!)

对于栈,我们描述的较为简单~完全基于第一篇文章动态数组的实现——第一篇文章传送门:动态数组的实现

 

第一步:声明一个Stack接口

1 public interface Stack<E> {
2     void push(E e); //push e into the stack
3     E pop();    //pop stack top element
4     E peek();   //view stack top elements
5     int getSize();  //view stack length
6     boolean isEmpty();  //check if the stack is empty
7 }

 

第二步:新建一个ArrayStack类去实现Stack接口

 1 public class ArrayStack<E> implements Stack<E> {
 2     /**
 3      * Based on Dynamic Array
 4      */
 5     private Array<E> array;
 6 
 7     public ArrayStack(int capacity) {
 8         array = new Array<>(capacity);
 9     }
10 
11     public ArrayStack() {
12         this(10);
13     }
14 
15     @Override
16     public void push(E e) {
17         array.addLast(e);
18     }
19 
20     @Override
21     public E pop() {
22         return array.removeLast();
23     }
24 
25     @Override
26     public E peek() {
27         return array.getLast();
28     }
29 
30     @Override
31     public int getSize() {
32         return array.getSize();
33     }
34 
35     @Override
36     public boolean isEmpty() {
37         return array.isEmpty();
38     }
39 
40 }

注:栈的实现完全是基于Array<E>类的,其入栈操作则是在数组末尾增加一个元素,也即是Array.addLast(E e)操作!

这些完全是我们在底层封装好了的,我们让用户看到的只是一个简简单单的栈   用户对于元素的操作也仅仅局限入栈和出栈以及查看栈顶元素~用户是无法查看到栈中间某个位置的元素,原因是我们规定了栈这样的特殊结构,在底层添加了限制!

 

栈的应用:栈的应用及其广泛,在计算机中可以说是无处不在~例如简单的撤销操作,每一次的操作通过栈去记录~若是想返回上一步,则栈弹出栈顶“元素”。】

 

在“力扣”中有一题关于括弧匹配~我们接下来,使用栈去完成——传送门:力扣括号匹配算法题

技术分享图片
class Solution {
    public class Array<E> {
    private E[] data;
    private int size;

    /**
     *
     * @param capacity
     */
    public Array(int capacity) {
        data = (E[]) new Object[capacity];
        size = 0;
    }

    /**
     * the default capacity is 10
     */
    public Array() {
        this(10);
    }

    /**
     *@return the current data length of the array
     */
    public int getSize() {
        return size;
    }

    /**
     * Determines whether the array is empty
     * @return  false or true
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * get the Array capacity
     * @return  Array capacity
     */
    public int capacity() {
        return data.length;
    }

    /**
     * Insert an element on an index
     * @param index
     * @param e
     */
    public void add(int index,E e) {
        if (index < 0 || index > size)
            throw new IllegalArgumentException("Add failed.Array is full");
        if (size == data.length) {
            resize(2*data.length);
        }
        for (int i = size - 1; i >= index; i--) {
            data[i+1] = data[i];
        }
        data[index] = e;
        size++;
    }

    private void resize(int newCapacity) {
        E[] newData = (E[]) new Object[newCapacity];
        for (int i = 0; i < size; i++) {
            newData[i] = data[i];
        }
        data = newData;
    }

    public void addLast(E e) {
        add(size,e);
    }
    /**
     * Get the value of the index location
     * @param index
     * @return
     */
    public E get(int index) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("Get failed,Array is full");
        return data[index];
    }

    /**
     * Specify index insert value
     * @param index
     * @param e
     */
    public void set(int index,E e) {
        if (index < 0 || index >= size)
            throw new IllegalArgumentException("set failed,Array is full");
        data[index] = e;
    }

    /**
     * Determine whether an array contains e
     * @param e
     * @return
     */
    public boolean contains(E e) {
        if (find(e) != -1)
            return true;
        else
            return false;
    }

    /**
     *find the index of "e" in the array
     * @param e
     * @return index of "e"
     */
    public int find(E e) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(e))
                return i;
        }
        return -1;
    }

    /**
     * remove elements from index positions
     * @param index
     * @return
     */
    public E remove(int index) {
        if (index < 0 || index >= size)
            throw  new IllegalArgumentException("remove failed,array is full");
        E ret = data[index];
        for (int i = index + 1; i < size; i++) {
            data[i - 1] = data[i];
        }
        size--;
        if (size == data.length / 4 && data.length / 2 != 0) {
            resize(data.length / 2);
        }
        return ret;
    }

    public E removeFirst() {
        return remove(0);
    }

    public void removeElement(E e) {
        if (find(e) != -1) {
            int index = find(e);
            for (int i = index + 1; i < size; i++)
                data[i-1] = data[i];
            size--;
        }
    }

    /**
     * remove all "e" from the array
     * @param e
     */
    public void removeElements(E e) {
        for (int i = 0; i < size; i++) {
            if (data[i].equals(e)) {
                remove(i);
                i--;
            }
        }
    }
    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array: size = %d , capacity = %d
",size,data.length));
        res.append("[");
        for (int i = 0; i < size; i++) {
            res.append(data[i]);
            if (i < size - 1)
                res.append(",");
        }
        res.append("]");
        return res.toString();
    }

    public E removeLast() {
        return remove(size - 1);
    }

    public E getLast() {
        return data[size - 1];
    }
}
    public class ArrayStack<E> implements Stack<E> {
    /**
     * Based on Dynamic Array
     */
    private Array<E> array;

    public ArrayStack(int capacity) {
        array = new Array<>(capacity);
    }

    public ArrayStack() {
        array = new Array<>();
    }

    @Override
    public void push(E e) {
        array.addLast(e);
    }

    @Override
    public E pop() {
        return array.removeLast();
    }

    @Override
    public E peek() {
        return array.getLast();
    }

    @Override
    public int getSize() {
        return array.getSize();
    }

    @Override
    public boolean isEmpty() {
        return array.isEmpty();
    }

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        str.append("Stack[");
        for (int i = 0; i < array.getSize() ; i++) {
            str.append(array.get(i));
            if(i < array.getSize() - 1) {
                str.append(",");
            }
        }
        str.append("] top");
        return String.valueOf(str);
    }
}
    public interface Stack<E> {
    void push(E e); //push e into the stack
    E pop();    //pop stack top element
    E peek();   //view stack top elements
    int getSize();  //view stack length
    boolean isEmpty();  //check if the stack is empty
}
    public boolean isValid(String s) {
        ArrayStack<Character> arrayStack = new ArrayStack<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ‘(‘ || c == ‘{‘ || c == ‘[‘) {
                arrayStack.push(c);
            } else {
                if (arrayStack.isEmpty())
                    return false;
                char topChar = arrayStack.pop();
                if (c == ‘)‘ && topChar != ‘(‘)
                    return false;
                if (c == ‘]‘ && topChar != ‘[‘)
                    return false;
                if (c == ‘}‘ && topChar != ‘{‘)
                    return false;
            }
        }
        return arrayStack.isEmpty();
    }
}
View Code

 代码很长,因为这次测试代码是使用了我们自己构建的数据结构去完成测试(如果不想使用自己的数据结构,可以导入java.util.Stack,使用Java提供的栈)

 

判断有效括弧的主要逻辑如下:

 1 public boolean isValid(String s) {
 2         ArrayStack<Character> arrayStack = new ArrayStack<>();  
 3         for (int i = 0; i < s.length(); i++) {  
 4             char c = s.charAt(i);
 5             if (c == ‘(‘ || c == ‘{‘ || c == ‘[‘) {
 6                 arrayStack.push(c); 
 7             } else {
 8                 if (arrayStack.isEmpty())
 9                     return false;
10                 char topChar = arrayStack.pop();
11                 if (c == ‘)‘ && topChar != ‘(‘)
12                     return false;
13                 if (c == ‘]‘ && topChar != ‘[‘)
14                     return false;
15                 if (c == ‘}‘ && topChar != ‘{‘)
16                     return false;
17             }
18         }
19         return arrayStack.isEmpty();
20     }

 

以上是关于基于动态数组实现栈(利用栈去实现括弧匹配)的主要内容,如果未能解决你的问题,请参考以下文章

利用数组实现栈

PTA-栈(括弧匹配)

栈的实现原理

利用队列实现栈

括号匹配算法思想

Java 栈 如何实现括号匹配