题解 | #表达式求值#
表达式求值
https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4
方法:栈+递归
利用栈存储数字和部分计算结果,用递归解决括号内的计算,递归出口是右括号,递归主体是遍历括号内进行计算,返回值是其结果。减法可以看作是 加上一个负数,所以就转化为都是加的问题了。
具体步骤:
1、建立一个递归函数用于计算表达式,类型为一个数组列表,参数为字符串和下标。
2、函数内先声明一个栈和符号标识符默认为加号。
3、遇到数字字符则将连续的数字字符都转化为数字。
4、遇到左括号,则递归解决子问题,返回为一个数组列表,里面存储的是计算的结果和子问题解决后的下标位置。
5、判断符号,加号则数字入栈,减号则数字的相反数入栈,乘号则将数字与栈顶相乘再入栈。
6、数字归零,方便下次遇见数字字符好计算,然后判断是否遇到右括号,不是则将当前的符号赋给符号标识符;是则说明该子问题结束跳出循环。
7、最后一部分是将栈中的数字都进行加法计算,将字符串的下标一并存入一个数组列表中,返回数列。
8、主函数中调用该函数,取第一个数作为返回值。
import java.util.*; public class Solution { //数组中存储的是部分结果值和当前遍历的下标 public ArrayList<Integer> function(String s,int index){ Stack<Integer> st = new Stack<Integer>(); int num=0; char op = '+'; int i; for(i=index;i<s.length();++i){ if(s.charAt(i)>='0'&&s.charAt(i)<='9'){ num = num*10 + s.charAt(i)-'0'; //转换为数字 if(i!= s.length()-1){ continue; } } if(s.charAt(i)=='('){ ArrayList<Integer> res = function(s,i+1); num = res.get(0); i = res.get(1); if(i!= s.length()-1){ continue; } } switch(op){ case '+': st.push(num); break; case '-': st.push(-num); break; case '*': int temp = st.pop(); st.push(temp*num); break; } //数字置零 num = 0; if(s.charAt(i) == ')'){ break; }else{ op = s.charAt(i); } } int sum=0; while(!st.isEmpty()){ sum +=st.pop(); } ArrayList<Integer> temp = new ArrayList<Integer>(); temp.add(sum); temp.add(i); return temp; } public int solve (String s) { ArrayList<Integer> res = function(s,0); return res.get(0); } }