题目地址: 链接
问题 A: 简单计算器
时间限制: 1 Sec 内存限制: 32 MB
提交: 1592 解决: 640
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
样例输出
12178.21
实现过程:
总体分为2个步骤:利用栈实现
- 将前缀表达式转换成后缀表达式 如何转换
- 计算后缀表达式
JAVA代码:
import java.text.DecimalFormat;
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
DecimalFormat df = new DecimalFormat("0.00");//格式化输出,保留两位小数
while(sc.hasNext()){
String str = sc.nextLine();
if(str.equals("0")) {//当遇到一行为0是停止输入,结束
sc.close();
break;
}
String postfix = toPostfix(str).toString();
double f = calrp(postfix);
System.out.println(df.format(f));
}
}
//进行计算弹出的栈的f1,f2
public static double getv(char op, double f1, double f2) {
if (op == '+') return f1 + f2;
else if (op == '-') return f2 - f1;
else if (op == '*') return f1 * f2;
else return f2 / f1;
}
//计算后缀表达式
public static double calrp(String rp) {
Stack<Double> v = new Stack<>();
String[] arr = rp.split(" ");
int len = arr.length;
for (int i = 0; i < len; i++) {
String str = arr[i];
if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/"))
v.push(getv(str.charAt(0), v.pop(), v.pop()));
//计算栈顶的两个数,计算完之后再次压栈
else {
v.push(Double.parseDouble(str));
}
}
return v.pop();
}
//获得前缀表达式
public static StringBuffer toPostfix(String infix) {
Stack<String> stack = new Stack<>();
StringBuffer postfix = new StringBuffer(infix.length() * 2);
int i = 0;
//System.out.println(infix);
String[] inf = infix.split(" ");
while (i < inf.length) {
switch (inf[i]) {
case "+":
case "-":
while (!stack.empty() && !stack.peek().equals("(")) {
postfix.append(stack.pop() + " ");//出栈,运算符添加到后缀表达式里面
}
stack.push(inf[i]);//当前入栈
i++;
break;
case "/":
case "*":
while (!stack.empty() && (stack.peek().equals("/") || stack.peek().equals("*"))) {
postfix.append(stack.pop() + " ");//栈顶优先级高的运算符出栈
}
stack.push(inf[i]);
i++;
break;
case "(":
stack.push(inf[i]);
i++;
break;
case ")":
//出 )
while (!stack.peek().equals("(") && !stack.isEmpty()) {
postfix.append(stack.pop() + " ");
}
if (stack.peek().equals("(")) {
stack.pop();
}
//出(
i++;
break;
default:
while (i < inf.length) {
postfix.append(inf[i] + " ");
i++;
break;
}
}
//将剩余的都弹出栈
}while (!stack.isEmpty()) {
postfix.append((stack.pop()) + " ");
}return postfix;
}
}
测试结果