一、棧的應用的實現
棧的應用很廣,函數的調用的底層實現,和實現表達式值得計算,可以實現括號的匹配,和瀏覽器的前進和後退的實現。
1、棧的表達式的計算。
package com.ypl.app;
import org.junit.Test;
import com.ypl.demo.ArrayStack;
/**
*
* 遇到數字直接壓人棧中。 左括號在進入棧中之前元素優先級最高。
* 左括號在進人棧後優先級最低。
* 遇到右括號,我們就不斷的彈出字符棧中的元素直到彈出左括號爲止。
* 遇到其餘的,我們比較優先級,如果優先級高於棧頂的元素,直接壓人棧中。
*
* @author ypl
*
*/
public class StackApplication {
/**
* 判斷是不是數字
*
* @param s
* @return
*/
private boolean isNum(char s) {
if (s >= '0' && s <= '9') {
return true;
}
return false;
}
/**
* 將字符轉換成數字
*
* @param c
* @return
*/
private int translateNum(char c) {
return c - '0';
}
@Test
public void addValue() {
// 1、定義兩個棧,一個棧是用於存儲表達式的值。一個是用來存儲表達式的運算符
ArrayStack<Integer> numStack = new ArrayStack<Integer>(10);
ArrayStack<Character> operatorStack = new ArrayStack<Character>(10);
// 2、表達式
String expression = "(3+5)*(8-6)";
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
// 1、判斷表達式是數字還是運算符
if (isNum(c)) {
numStack.push(translateNum(c));
}
// 2、如果是運算符
else {
if (operatorStack.isEmpty() || c == '(') { // 如果表達式是空 或者說是 左括號
operatorStack.push(c);
} else if (c == ')') { // 否則取出棧頂元素。
while (operatorStack.peek() != '(') {
char topc = operatorStack.pop(); // 獲取表達式的運算符
int num2 = numStack.pop(); // 獲取表達式的值num1
int num1 = numStack.pop(); // 獲取表達式的值num2
int value = operator(num1, topc, num2);
numStack.push(value);
}
operatorStack.pop();
} else {
char topc = operatorStack.peek();
while (!comPriority(topc, c) && !operatorStack.isEmpty()) { // 如果優先級低於棧頂元素
operatorStack.pop();
int num2 = numStack.pop(); // 獲取表達式的值num1
int num1 = numStack.pop(); // 獲取表達式的值num2
int value = operator(num1, topc, num2);
numStack.push(value);
if(operatorStack.isEmpty()){
break;
}else{
topc = operatorStack.peek();
}
}
if (comPriority(topc, c) || operatorStack.isEmpty()) { // 如果比棧頂的優先級高
operatorStack.push(c); // 直接壓人棧頂元素
}
}
}
}
while(!operatorStack.isEmpty()){ //獲取數字
char topc =operatorStack.pop();
int num2 = numStack.pop(); // 獲取表達式的值num1
int num1 = numStack.pop(); // 獲取表達式的值num2
int value = operator(num1, topc, num2);
numStack.push(value);
}
int num=numStack.pop();
System.out.println(num);
}
/**
* 計算表達式的值
*
* @param num1
* @param c
* @param num2
* @return
*/
private int operator(int num1, char c, int num2) {
int value = 0;
switch (c) {
case '+': {
value = num1 + num2;
break;
}
case '-': {
value = num1 - num2;
break;
}
case '*': {
value = num1 * num2;
break;
}
case '/': {
value = num1 / num2;
break;
}
default:
throw new IllegalArgumentException("現在不支持該運算符");
}
return value;
}
/**
* 優先級的比較 如果棧頂元素的優先級低,返回true 否則返回false
*
* @param topc
* @param c
* @return
*/
private boolean comPriority(char topc, char c) {
if ((topc == '+' || topc == '-') && (c == '*' || c == '/')) {
return true;
}
if (topc == '(' && c != '(') {
return true;
}
return false;
}
}
2、棧的瀏覽器的前進和後退按鈕的實現
public class SimpleBrrower<T> {
private Stack<T> forwardStack;
private Stack<T> backStack;
private T currentPager;
public SimpleBrrower() {
forwardStack = new ArrayStack<T>();
backStack = new ArrayStack<T>();
currentPager = null;
}
/**
* 表示的是打開頁面
*/
public void open(T url) {
backStack.push(url);
forwardStack.clear(); //每次打開一個新的頁面,我們必須清空forwardStack的元素。
showUrl("open", url);
}
/**
* 顯示頁面
*
* @param prefix
* @param url
*/
private void showUrl(String prefix, T url) {
currentPager = url;
System.out.println(prefix + " page == " + url);
}
/**
* 返回頁面
*
* @return
*/
public T goBack() {
if (this.canGoBack()) {
T backUrl = this.backStack.pop();
this.forwardStack.push(backUrl);
showUrl("Back", backUrl);
this.currentPager = backStack.peek();
return backUrl;
}
System.out.println("* Cannot go back, no pages behind.");
return null;
}
/**
* 前進頁面
*
* @return
*/
public T goForward() {
if (this.canGoForward()) {
T forwardUrl = this.forwardStack.pop();
showUrl("Foward", currentPager);
this.backStack.push(forwardUrl);
this.currentPager = forwardUrl;
return forwardUrl;
}
System.out.println("** Cannot go forward, no pages ahead.");
return null;
}
/**
* 是否能夠返回
*
* @return
*/
public boolean canGoBack() {
return this.backStack.getSize() > 1;
}
/**
* 是否能夠前進
*
* @return
*/
public boolean canGoForward() {
return this.forwardStack.getSize() > 0;
}
/**
* 返回當前頁面
*/
public void checkCurrentPage() {
System.out.println("Current page is: " + this.currentPager);
}
public static void main(String[] args) {
SimpleBrrower browser = new SimpleBrrower<String>();
// browser.open("首頁");
browser.open("http://www.baidu.com");
browser.open("http://news.baidu.com/");
browser.open("http://news.baidu.com/ent");
browser.checkCurrentPage();
browser.goBack(); //返回的頁面是
browser.checkCurrentPage();
browser.goBack();
browser.checkCurrentPage();
System.out.println("---------------------");
browser.goForward();
browser.checkCurrentPage();
browser.open("http://www.qq.com");
browser.goForward();
browser.goBack(); //返回qq
browser.checkCurrentPage();
browser.goForward(); //前進一頁。
browser.checkCurrentPage();
browser.goBack();
browser.checkCurrentPage();
browser.goBack();
browser.checkCurrentPage();
browser.goBack();
browser.checkCurrentPage();
browser.goBack();
browser.checkCurrentPage();
}
}