一、题目描述
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’
。且表达式一定合法。
数据范围:表达式计算结果和过程中满足∣val∣≤1000
,字符串长度满足 1≤n≤1000
。
二、输入描述
输入一个算术表达式。
三、输出描述
得到计算结果。
四、解题思路
- 读取输入的算术表达式字符串 s;
- 初始化变量 num1 为0,用于保存当前运算结果;
- 初始化变量 o1 为1,表示当前运算符的符号,默认为正号;
- 初始化变量 num2 为1,用于保存当前数字的值;
- 初始化变量 o2 为1,表示当前乘除运算符的符号,默认为正号;
- 创建一个栈 stk,用于保存计算过程中的状态;
- 遍历表达式字符串 s的每个字符 c:
- 若 c 是数字字符,则将连续的数字字符解析成一个整数 cur,并根据 o2 的符号进行乘除运算,更新 num2 的值;
- 若 c 是乘除运算符字符 * 或 /,更新 o2 的符号;
- 若 c 是左括号字符 ( 或 { 或 [,将当前的运算结果和运算符状态压入栈中,并初始化 num1、o1、num2、o2 的值;
- 若 c 是加减运算符字符 + 或 -,表示可以开始计算结果了,根据 o1 的符号将当前的 num2 加或减到 num1 上,并更新 o1 和 o2 的值,重新初始化 num2 为1;
- 若 c 是右括号字符 ) 或 } 或 ],表示一个括号内的表达式结束,从栈中弹出之前保存的运算状态,并根据弹出的状态重新计算 num2 的值;
- 计算结束后,输出最终结果 num1 + o1 * num2;
五、Java算法源码
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int n = s.length();
int num1 = 0;
int o1 = 1;
int num2 = 1;
int o2 = 1;
Stack<Integer> stk = new Stack<>();
for(int i=0; i<n; i++){
char c = s.charAt(i);
if(Character.isDigit(c)){ //遇到数字则定义num2
int cur = 0;
while(i<n && Character.isDigit(s.charAt(i))){
cur = cur * 10 + (s.charAt(i) - '0');
i++;
}
i--;
num2 = o2 == 1 ? num2 * cur : num2 / cur;
}else if(c=='*' || c=='/'){ //遇到×÷定义o2
o2 = c == '*' ? 1 : -1;
}else if(c == '(' || c=='{' || c=='['){ //遇到括号则保存当前结果,并初始化
stk.push(num1);
stk.push(o1);
stk.push(num2);
stk.push(o2);
num1 = 0;
o1 = 1;
num2 = 1;
o2 = 1;
}else if(c == '+' || c=='-'){ //遇到加减,说明可以开始计算,计算num1并对定义其他几个变量
if(c=='-' && (i==0 || s.charAt(i-1)=='(' || s.charAt(i-1)=='[' || s.charAt(i-1)=='{')){
o1 = -1;
continue;
}
num1 = num1 + o1 * num2;
o1 = (c == '+' ? 1 : -1);
num2 = 1;
o2 = 1;
}else{ //遇到右括号,则出栈,并计算num2
int cur = num1 + o1 * num2;
o2 = stk.pop();
num2 = stk.pop();
o1 = stk.pop();
num1 = stk.pop();
num2 = o2 == 1 ? num2 * cur : num2 / cur;
}
}
System.out.println(num1 + o1 * num2);
}