微信搜索:碼農StayUp
主頁地址:https://gozhuyinglong.github.io
源碼分享:https://github.com/gozhuyinglong/blog-demosjava
棧又叫堆棧,是一種運算受限制的線性表,限定只能在一端進行插入和刪除操做,該端稱爲棧頂(Top),相對的另外一端叫棧底(Bottom)。git
根據棧的定義可知,最早進入棧的元素在棧底,最後進入棧的元素在棧頂。而刪除元素恰好相反,即刪除順序從棧頂到棧底github
對棧的操做只有兩種:數組
棧是一個先進後出(FILO - First In Last Out)的有序列表。在上圖中描述了棧的模型,咱們對棧的操做只有push
和pop
,棧頂元素是該棧惟一可見的元素。微信
因爲棧是一個表,所以任何實現表的方法都能實現棧。顯然咱們以前用到的《 數組 》和《 鏈表 》均可以實現棧。下面代碼是使用數組實現的一個棧。工具
size
表示棧內元素的大小,棧頂元素爲 elementData[size - 1],棧底元素爲 elementData[0]。入棧時執行 size++,出站時執行 size--this
public class StackDemo { public static void main(String[] args) { System.out.println("-------------------入站"); Stack<String> stack = new Stack<>(10); stack.push("a"); stack.push("b"); stack.push("c"); stack.push("d"); stack.push("e"); stack.print(); System.out.println("元素大小: " + stack.size()); System.out.println("棧容量: " + stack.capacity()); System.out.println("-------------------出站"); System.out.println("出站元素: " + stack.pop()); System.out.println("出站元素: " + stack.pop()); stack.print(); System.out.println("元素大小: " + stack.size()); System.out.println("棧容量: " + stack.capacity()); } private static class Stack<E> { private int size; // 元素大小 private final int capacity; // 棧的容量 transient Object[] elementData; // 元素數據 public Stack(int capacity) { if (capacity <= 0) { throw new IllegalArgumentException("Illegal Capacity: " + capacity); } else { this.capacity = capacity; elementData = new Object[capacity]; } } /** * 獲取棧的元素大小 * * @return */ public int size() { return size; } /** * 獲取棧的容量 * * @return */ public int capacity() { return capacity; } /** * 入棧 * * @param e * @return */ public boolean push(E e) { if (size >= capacity) { return false; } elementData[size++] = e; return true; } /** * 出棧 * * @return */ public E pop() { if (size <= 0) { return null; } return (E) elementData[--size]; } /** * 打印元素數據 */ public void print() { System.out.print("站內元素: "); for (int i = 0; i < size; i++) { System.out.printf("%s\t", elementData[i]); } System.out.println(); } } }
輸出結果:.net
-------------------入站 站內元素: a b c d e 元素大小: 5 棧容量: 10 -------------------出站 出站元素: e 出站元素: d 站內元素: a b c 元素大小: 3 棧容量: 10
編譯器檢查程序的語法錯誤時,經常會由於缺乏一個符號(如遺漏一個花括號等)引發編譯器上列出上百行的診斷,而真正的錯誤並無找出。在這種狀況下,若是能有一個工具可以檢測括號必須成對出現那就行了,這即可以使用棧進行解決。code
下面代碼使用了Java自帶的Stack
類進行實現。字符串[ ( ) ]
是合法的,而[ ( ] )
是錯誤的。blog
代碼實現:
public class StackDemoBalancedChar { public static void main(String[] args) { BalancedChar balancedChar = new BalancedChar(); String str = "[()][{}][][((()))]"; boolean ok = balancedChar.isOk(str); System.out.printf("字符串:%s\t----> %s", str, ok); } private static class BalancedChar { private final char[] openArray = {'(', '[', '{'}; // 左括號 private final char[] closeArray = {')', ']', '}'}; // 右括號 /** * 判斷字符串是否正確 * * @param str * @return */ public boolean isOk(String str) { // 使用 Java 自帶的 Stack 類 Stack<Character> stack = new Stack<>(); boolean ok = true; // 判斷字符串是否正確 for (char c : str.toCharArray()) { // 若不是平衡符則忽略 if (!isBalancedChar(c)) { continue; } // 若是是左括號,則入棧 if (isOpen(c)) { stack.push(c); continue; } // 若是是右括號,而棧爲空則報錯 if (stack.empty()) { ok = false; break; } // 若是是右括號,從棧中取出一個元素,並與當前元素判斷是不是一對,若不是一對則報錯 Character open = stack.pop(); if (!isTwain(open, c)) { ok = false; } } return ok && stack.empty(); } /** * 是否爲左括號 * * @param c * @return */ public boolean isOpen(char c) { return inArray(openArray, c); } /** * 是否爲右括號 * * @param c * @return */ public boolean isClose(char c) { return inArray(closeArray, c); } /** * 是不是平衡符 */ public boolean isBalancedChar(char c) { return isOpen(c) || isClose(c); } /** * 是否在數組中 * * @param charArray * @param c * @return */ public boolean inArray(char[] charArray, char c) { for (char c1 : charArray) { if (c1 == c) { return true; } } return false; } /** * 是否一對平衡符 * * @param open * @param close * @return */ public boolean isTwain(char open, char close) { switch (open) { case '(': if (close == ')') { return true; } case '[': if (close == ']') { return true; } case '{': if (close == '}') { return true; } default: return false; } } } }
輸出結果:
字符串:[()][{}][][((()))] ----> true