一、栈的应用的实现
栈的应用很广,函数的调用的底层实现,和实现表达式值得计算,可以实现括号的匹配,和浏览器的前进和后退的实现。
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();
}
}