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

}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值