3、棧的應用

一、棧的應用的實現

棧的應用很廣,函數的調用的底層實現,和實現表達式值得計算,可以實現括號的匹配,和瀏覽器的前進和後退的實現。

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();
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章