一、题目描述
输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘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)){ //遇到数字则定义num2int 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=='/'){ //遇到×÷定义o2o2 = 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{ //遇到右括号,则出栈,并计算num2int 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);
}