package cn.my.stack;
import java.util.Stack;
/**
* 利用栈的特性进行表达式求值
*
* @author zhu
*
*/
public class ExpressionValue {
// 定义一个操作数栈
private static Stack<Integer> numberStack = new Stack<Integer>();
// 定义一个操作符栈
private static Stack<Character> operatorStack = new Stack<Character>();
public static void main(String[] args) throws Exception {
System.out.println(expGetValue());
}
/**
* @param operator
* 操作符
* @return 操作符的优先级
*/
public static int getPriority(char operator) {
switch (operator) {
case '*':
return 2;
case '/':
return 2;
case '+':
return 1;
case '-':
return 1;
case '#':
return 0;
}
return 0;
}
/**
* @param x
* @param operator
* @param y
* @return 按指定操作符计算两个操作数的到的结果
*/
public static int operate(Integer x, char operator, Integer y) {
switch (operator) {
case '*':
return x * y;
case '/':
return x / y;
case '+':
return x + y;
case '-':
return x - y;
}
return 0;
}
/**
* @return 表达是的值
* @throws Exception
*/
public static int expGetValue() throws Exception {
// 定义要存储字符和操作符的变量
char ch;
char operator;
// 存储操作数和结果的变量
Integer x, y, result;
// 初始化运算符集合
String operators = "+ - * / #";
// 栈初始化,在栈底压入表达式左边虚设的字符"#",用于以后判断计算是否结束
operatorStack.push('#');
// 读入一个字符
ch = (char) System.in.read();
// 如果字符不是"#"或者操作符栈的站顶元素不是"#"则继续
while (ch != '#' || operatorStack.peek() != '#') {
// 如果输入的字符不在操作符集合中
if (!operators.contains(String.valueOf(ch))) {
// 注意System.in.read()读入时,键盘上的任何一个键都会被当做时输入值,包括Enter,当我们按下Enter时,实际上发送了
// 两个值一个回车\t,一个换行\n,所以在判断字符时要把这两个值滤去
if (ch != '\n' && ch != '\r') {
// 把字符所代表的数值压入操作数栈
numberStack.push(Character.getNumericValue(ch));
}
// 再读入一个字符
ch = (char) System.in.read();
} else if (getPriority(ch) > getPriority(operatorStack.peek())) { // 如果新读入的操作符的优先级比操作符栈顶元素的优先级高
if (ch != '\n' && ch != '\r') {
// 则把操作符压入操作符栈
operatorStack.push(ch);
}
// 在读入一个字符
ch = (char) System.in.read();
} else { // 如果新读入的操作符的优先级比操作符栈顶元素的优先级低
// 弹出位于操作符栈顶端的操作符
operator = operatorStack.pop();
// 弹出两个操作数
x = numberStack.pop();
y = numberStack.pop();
// 计算结果
result = operate(y, operator, x);
// 把中间结果压入操作数栈
numberStack.push(result);
}
}
// 最终操作数栈顶的元素就是表达式的值
return numberStack.pop();
}
}
import java.util.Stack;
/**
* 利用栈的特性进行表达式求值
*
* @author zhu
*
*/
public class ExpressionValue {
// 定义一个操作数栈
private static Stack<Integer> numberStack = new Stack<Integer>();
// 定义一个操作符栈
private static Stack<Character> operatorStack = new Stack<Character>();
public static void main(String[] args) throws Exception {
System.out.println(expGetValue());
}
/**
* @param operator
* 操作符
* @return 操作符的优先级
*/
public static int getPriority(char operator) {
switch (operator) {
case '*':
return 2;
case '/':
return 2;
case '+':
return 1;
case '-':
return 1;
case '#':
return 0;
}
return 0;
}
/**
* @param x
* @param operator
* @param y
* @return 按指定操作符计算两个操作数的到的结果
*/
public static int operate(Integer x, char operator, Integer y) {
switch (operator) {
case '*':
return x * y;
case '/':
return x / y;
case '+':
return x + y;
case '-':
return x - y;
}
return 0;
}
/**
* @return 表达是的值
* @throws Exception
*/
public static int expGetValue() throws Exception {
// 定义要存储字符和操作符的变量
char ch;
char operator;
// 存储操作数和结果的变量
Integer x, y, result;
// 初始化运算符集合
String operators = "+ - * / #";
// 栈初始化,在栈底压入表达式左边虚设的字符"#",用于以后判断计算是否结束
operatorStack.push('#');
// 读入一个字符
ch = (char) System.in.read();
// 如果字符不是"#"或者操作符栈的站顶元素不是"#"则继续
while (ch != '#' || operatorStack.peek() != '#') {
// 如果输入的字符不在操作符集合中
if (!operators.contains(String.valueOf(ch))) {
// 注意System.in.read()读入时,键盘上的任何一个键都会被当做时输入值,包括Enter,当我们按下Enter时,实际上发送了
// 两个值一个回车\t,一个换行\n,所以在判断字符时要把这两个值滤去
if (ch != '\n' && ch != '\r') {
// 把字符所代表的数值压入操作数栈
numberStack.push(Character.getNumericValue(ch));
}
// 再读入一个字符
ch = (char) System.in.read();
} else if (getPriority(ch) > getPriority(operatorStack.peek())) { // 如果新读入的操作符的优先级比操作符栈顶元素的优先级高
if (ch != '\n' && ch != '\r') {
// 则把操作符压入操作符栈
operatorStack.push(ch);
}
// 在读入一个字符
ch = (char) System.in.read();
} else { // 如果新读入的操作符的优先级比操作符栈顶元素的优先级低
// 弹出位于操作符栈顶端的操作符
operator = operatorStack.pop();
// 弹出两个操作数
x = numberStack.pop();
y = numberStack.pop();
// 计算结果
result = operate(y, operator, x);
// 把中间结果压入操作数栈
numberStack.push(result);
}
}
// 最终操作数栈顶的元素就是表达式的值
return numberStack.pop();
}
}