基于动态数组实现栈(利用栈去实现括弧匹配)
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(); } }
代码很长,因为这次测试代码是使用了我们自己构建的数据结构去完成测试(如果不想使用自己的数据结构,可以导入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 }
以上是关于基于动态数组实现栈(利用栈去实现括弧匹配)的主要内容,如果未能解决你的问题,请参考以下文章