您的位置:首页 > 编程语言 > Java开发

Java实现表达式的运算

2016-06-06 00:37 316 查看
最近在做个C++课设,需要根据输入的表达式计算出结果。本人是学Android的,感觉这算法经常用到,就用Java实现了一遍。

我们平时接触的表达式是中缀表达式,如:12 * ( 8 - 3 ) - 20 。我们很简单就能算出结果为40,但计算机不行,我们要告诉它怎么算,就需要把中缀表达式转换为后缀表达式了。

基本思路:顺序扫描中缀表达式,当读入一个运算分量时就立即输出;而读入一个运算符时,先将它放进一个运算符栈中,一直等到这个运算符的两个运算分量都读到后,才输出。但运算符的优先级不同,需要遵守下面的规则:

读到运算分量,直接输出;
栈为空时,读到操作符,直接进栈;
左括号的优先级被视为比所有运算符低,读到左括号,直接进栈;
读到右括号,把栈中左括号上面的元素输出,并把左括号弹出;
读到其他运算符,输出所有优先级大于或等于该运算符的栈顶元素;
最后把栈中剩余的元素一一输出。

例如用上面表达式举例:12 * ( 8 - 3 ) - 20

中缀表达式运算符栈(顶--底)后缀表达式
12 * ( 8 - 3 ) - 20
* ( 8 - 3 ) - 2012
( 8 - 3 ) - 20*12
8 - 3 ) - 20( *12
- 3 ) - 20( *12 8
3 ) - 20- ( *12 8
) - 20- ( *12 8 3
- 20*12 8 3 -
20-12 8 3 - *
-12 8 3 - * 20
12 8 3 - * 20 -
ps. 后缀表达式不包含左右括号的。

代码如下:

/**
* 中缀表达式转换为后缀表达式
* @param infix 中缀表达式
* @return 返回后缀表达式
*/
List<String> infix2Postfix(List<String> infix) {
List<String> postfix = new ArrayList<>();

Stack<String> stack = new Stack<>();
int len = infix.size();
String temp;

for(int i = 0; i < len; i++) {
temp = infix.get(i);

if(temp.equals(" "))
continue;

if(temp.equals(LEFT_BRACKET)) {
stack.push(temp);
} else if (temp.equals(RIGHT_BRACKET)) {
while(!stack.peek().equals(LEFT_BRACKET)) {
postfix.add(stack.pop());
}
stack.pop();	// 把左括号弹出
} else {
if(!isOperator(temp)) {		// 若为操作数
postfix.add(temp);
} else {
// 从栈中弹出所有优先级比当前运算符高的运算符, 并放进队列中
while(!stack.isEmpty()
&& compareOperatorPriority(stack.peek(), temp) >= 0) {
postfix.add(stack.pop());
}
stack.push(temp);	// 操作符进栈
}
}
}

// 把栈中的所有元素弹出, 放进队列中
while(!stack.isEmpty()) {
postfix.add(stack.pop());
}

return postfix;
}


接下来就是由后缀表达式求值了。

基本思路:顺序扫描后缀表达式,读到运算分量时,将它放进栈中;当读到运算符时,就从栈中弹出两个运算分量进行计算,再把结果压进栈中。扫描到结束,栈顶元素就是所求表达式的值。

还是拿上面的例子来举例:

后缀表达式运算分量栈(顶--底)进行的计算
12 8 3 - * 20 -
8 3 - * 20 -12
3 - * 20 -8 12
- * 20 -3 8 12
* 20 -5 128 - 3 = 5 压进栈
20 -6012 * 5 = 60 压进栈
-20 60
4060 - 20 = 40 压进栈
40计算结束
代码如下:

/**
* 由后缀表达式计算表达式的结果
* @param postfix 后缀表达式
* @return 返回表达式的结果
*/
double calculate(List<String> postfix) {

Stack<Double> stack = new Stack<>();
int len = postfix.size();
String temp;

for(int i = 0; i < len; i++) {
temp = postfix.get(i);
if(!isOperator(temp)) {		// 若为操作数
stack.push(Double.parseDouble(temp));
} else {
double val = 0;
double num1 = stack.pop();
double num2 = stack.pop();
switch (temp) {
case ADD:
val = num2 + num1;
break;

case SUB:
val = num2 - num1;	// 注意顺序哦!
break;

case MUL:
val = num2 * num1;
break;

case DEV:
val = num2 / num1;
break;

default:
break;
}
stack.push(val);
}
}

return stack.pop();
}


附上Demo:Demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 算法 数据结构