题解 | #四则运算#
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
//思路:1.先将所有括号替换为小括号 2.处理所有小括号中的表达式,将计算结果存在一个全局变量map映射中3.最后计算整个不含括号的表达式
import java.util.*;
import java.lang.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
LinkedHashMap<Character,Integer> lhm = new LinkedHashMap<>();//用于存放小括号中子表达式的计算结果
public static void main(String[] args) {
String s = new Scanner(System.in).nextLine();
s=s.replaceAll("[\\[\\{]","(");
s=s.replaceAll("[\\]\\}]",")");
Main me = new Main();
char a='A';
//使用while循环处理子表达式,直至最终的表达式中不含括号
while (s.contains("(")){
int indl = s.lastIndexOf("(");
int indr = s.indexOf(")",indl);
StringBuilder sb = new StringBuilder();
sb.append(s);
String s0 = s.substring(indl+1,indr);
int sum0 = me.evalbase(s0);
//使用原表达式中不可能出现的字符替换子表达式的计算结果,将其映射的value值存在全局变量lhm中
me.lhm.put(a,sum0);
sb.replace(indl,indr+1,Character.toString(a));
s=sb.toString();
a+=1;
}
//将最后的表达式计算后输出结果
System.out.println(me.evalbase(s));
}
//计算不含括号的表达式的方法:
int evalbase(String s){
Stack<Integer> st = new Stack<>();
char preop='+';//预置上一个符号为“+”
int step=0;//用来存放for循环的步长,数字为对应数字的长度,符号为1
//将数字、加减乘除分别处理,遇见数字则往后取直到取完整个数字串,将取到的数字按照其前边的符号处理后推入栈
for (int i=0;i<s.length();i+=step){
char ci = s.charAt(i);
//---处理数字,两种情况:数字串和映射在全局map变量中的值
if (Character.isDigit(ci) || (ci>='A' && ci<='Z')){
int num=0;step=0;//每次取数前将num和步长置0
while (Character.isDigit(ci)){//使用while循环取数字串
step+=1;
num = num*10+(ci-'0');
if (i+step>s.length()-1){
break;//若已到最后一位,跳出循环
}
ci = s.charAt(i+step);
}
if (ci>='A' && ci<='Z'){//根据key取出映射在全局变量中的子表达式计算结果(因为只定义到Z,所以只支持不超过26个括号的表达式)
step+=1;
num=this.lhm.get(ci);
}
//若数字前边符号为减乘以-1,为*则弹出上一个数字相乘,为/则弹出上一个数字相除,为+的不做处理
switch (preop){
case '-':
num =-1*num;break;
case '*':
num = st.pop()*num;break;
case '/':
num = st.pop()/num;break;
}
st.push(num);
}else if (ci=='-' || ci=='*' || ci=='/' || ci=='+'){
preop = ci;step=1;//设置符号时将for循环的步长设置为1
}
}
//将栈中的所有数字相加后输出
int re = st.stream().mapToInt(no->no).sum();
return re;
}
}


