利用栈的特性对一个表达式求值
2016-06-05 01:28
239 查看
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();
}
}
相关文章推荐
- View的事件体系
- 10039---OutputStream & Writer
- [Hackerrank] The Coin Change Problem
- C++虚函数表与虚析构函数
- 正则表达式、分组、子匹配(子模式)、非捕获子匹配(子模式)
- DW 破解方法
- genymotion安装及使用出现的问题
- SpringMvc入门五----文件上传
- 数据库触发器inserted和deleted详解
- Mysql数据类型
- ppp协议基本介绍
- 【代码笔记】Java深入学习——实现客户端发送文件到服务器的文件传输
- spring + redis 实现数据的缓存
- 黑客增长
- Spring Data Redis—Pub/Sub(附Web项目源码)
- 正则表达式性能优化方法(高效正则表达式书写)
- Android自定义View流程
- python的学习笔记简要总结一
- 对Window和WindowManager的理解
- 提要求,学习html5,完善自己的个人网站,体会不一样的现实心情