输入一个数学表达式,有不同优先级的运算符和括号,计算表达式的结果
二元运算符位于两个操作数之间的表达式成为中缀表达式。一般输入的数学表达式都是中缀表达式。与之相对应的,二元操作符位于两个操作数之后的表达式称为后缀表达式(又称逆波兰表达式),二元运算符位于两个操作数之前的表达式称为前缀表达式。中缀表达式(逆波兰表达式)便于计算机计算。
----------------------------------------
1. 将输入的中缀表达式转化为后缀表达式【Algorithm 1】
2. 计算后缀表达式【Algorithm 2】
----------------------------------------
【Algorithm 1】中缀表达式 -> 后缀表达式
初始化操作数栈operand
初始化运算符栈operator
1. 从左到右扫描输入的中缀表达式
2. 如果此字符是操作数,则operand入栈
3. 如果此字符是运算符
3.1 如果该运算符是"(",operator入栈
3.2 如果该运算符是"+,-,*,/",从栈顶开始,与该运算符相比优先级相等或更高的运算符依次operator出栈并operand入栈,直到栈顶是比该运算符优先级低的运算符或"("或operator栈空,然后该运算符自己operator入栈
3.3 如果该运算符是")",从栈顶开始运算符依次operator出栈并operand入栈直到栈顶是"("
4. 此时操作数栈operand从栈底到栈顶就是后缀表达式
【Algorithm 2】计算后缀表达式的值
初始化计算栈answer
1. 从左到右扫描后缀表达式
2. 如果此字符是数字,则answer入栈
3. 如果此字符是运算符,则取answer栈顶2个元素计算,将计算结果answer入栈
4. 最后answer中剩下的那个数就是后缀表达式的计算结果
简单起见,仅考虑一位整数和加法、乘法两种运算符以及括号
/*
* 表达式计算器类
* 支持一位整数的加法、乘法、括号的综合表达式计算
算法:
----------------------------------------
1. 将输入的中缀表达式转化为后缀表达式【Algorithm 1】
2. 计算后缀表达式【Algorithm 2】
----------------------------------------
【Algorithm 1】中缀表达式 -> 后缀表达式
初始化操作数栈operand
初始化运算符栈operator
1. 从左到右扫描输入的中缀表达式
2. 如果此字符是操作数,则operand入栈
3. 如果此字符是运算符
3.1 如果该运算符是"(",operator入栈
3.2 如果该运算符是"+,-,*,/",从栈顶开始,与该运算符相比优先级相等或更高的运算符依次operator出栈并operand入栈,直到栈顶是比该运算符优先级低的运算符或"("或operator栈空,然后该运算符自己operator入栈
3.3 如果该运算符是")",从栈顶开始运算符依次operator出栈并operand入栈直到栈顶是"("
4. 此时操作数栈operand从栈底到栈顶就是后缀表达式
【Algorithm 2】计算后缀表达式的值
初始化计算栈answer
1. 从左到右扫描后缀表达式
2. 如果此字符是数字,则answer入栈
3. 如果此字符是运算符,则取answer栈顶2个元素计算,将计算结果answer入栈
4. 最后answer中剩下的那个数就是后缀表达式的计算结果
*/
package expression;
import calculator.Calculator;
import java.util.Stack;
public class ExpressionCal extends Calculator{
public int calculateExpr(String expr)
{
// 1. 将中缀表达式化成后缀表达式
Stack operand = new Stack(); // 操作数栈
Stack operator = new Stack(); // 运算符栈
int i = 0, len = expr.length();
char c,c1; // c:接收expr的字符, c1:operator栈顶弹出的元素
for (i=0; i ans = new Stack(); // 计算结果
int cint, cint1; // 由字符opr转化而成的整数
for (Character opr : operand) // 从左到右扫描operand
{
if (Character.isDigit(opr)) // 如果opr是数字
{
cint = (int)(opr-'0'); // 将opr转化为int
ans.add(cint); // 将cint入栈ans
}
else if (opr=='+') // 是加号
{
cint = ans.pop(); // 从ans栈顶弹出两个数cint和cint1
cint1 = ans.pop();
cint = addition(cint,cint1); // 两数相加
ans.add(cint); // 计算结果写回ans
}
else if (opr=='*') // 是乘号
{
cint = ans.pop(); // 从ans栈顶弹出两个数cint和cint1
cint1 = ans.pop();
cint = multiple(cint,cint1); // 两数相加
ans.add(cint); // 计算结果写回ans
}
}
return ans.pop(); // 最后ans栈中剩下的那个数就是计算结果
}
}
/*
* 运行表达式计算类ExpressionCal的main方法入口
* 从控制台输入表达式,在控制台输出计算结果
*/
package expression;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class RunExpressionCal {
public static void main(String args[])
{
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println
("Please enter an expression with +,*,() and 1-digit integer:");
String expr = br.readLine();
ExpressionCal exprcal = new ExpressionCal();
int ans = exprcal.calculateExpr(expr);
System.out.println("The answer is: "+ans);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}