题解 | #表达式计算#
表达式求值
http://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4
解题思路:
用两个栈来模拟表达式运算的过程;
一个数字栈和一个符号栈;
具体运算过程如注释所示:
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 返回表达式的值
* @param s string字符串 待计算的表达式
* @return int整型
*/
public int solve (String s) {
// write code here
char[] c=s.toCharArray();
Stack<Integer> intS=new Stack<>();
Stack<Character> syS=new Stack<>();
int i=0;
int res=0;
while(i<c.length){
//左括号直接入符号栈
if(c[i]=='(')
syS.push(c[i]);
else if(c[i]==')'){
//右括号则循环判断符号栈栈顶是否是左括号,若不是则计算数字栈顶的两个值
while(syS.peek()!='('){
res=compute(intS.pop(),intS.pop(),syS.pop());
intS.push(res);
}
//此时遇到左括号,将左括号出栈即可
syS.pop();
}
//判断是否是数字
else if(Character.isDigit(c[i])){
int j=i+1;
String num=""+c[i];
//计算多位数字字符构成的数字
while(j<c.length&&Character.isDigit(c[j])){
num=num+c[j];
j++;
}
//将数字入数字栈
intS.push(strToInt(num));
i=j;
continue;
}else{
//剩下的情况遇到运算符,比较当前运算符和栈顶运算符的优先级,若当前优先级大则直接入栈,否则字符栈出栈,并计算数字栈头两个数字的值。
if(syS.isEmpty()||compare(c[i],syS.peek())){
syS.push(c[i]);
}else{
//优先级更低,先计算符号栈栈顶的运算符
while(!compare(c[i],syS.peek())){
res=compute(intS.pop(),intS.pop(),syS.pop());
intS.push(res);
//若符号栈为空则表示计算完毕
if(syS.isEmpty())
break;
}
//此时符号栈剩下的运算符优先级更低,直接将当前运算符入栈
syS.push(c[i]);
}
}
i++;
}
//符号栈还不为空说明没有计算完
while(!syS.isEmpty()){
res=compute(intS.pop(),intS.pop(),syS.pop());
intS.push(res);
}
return res;
}
public int strToInt(String s){
int len=s.length();
int res=0;
for(int i=0;i<len;i++){
res+=Integer.valueOf(s.substring(i,i+1))*Math.pow(10,len-1-i);
}
return res;
}
public int compute(int a,int b,char c){
if(c=='*')
return a*b;
if(c=='-')//注意这里做减法和除法要用后一个减(除)前一个,因为栈是先进后出和数学计算规则是相反的
return b-a;
if(c=='+')
return a+b;
if(c=='/')
return b/a;
return 0;
}
public boolean compare(char c,char d){
//这里判断优先级,别忘了左括号的优先级是最低的,
if(c=='*'||c=='/'){
if(d=='+'||d=='-'||d=='(')
return true;
else
return false;
}
if(c=='-'||c=='+'){
if(d=='(')
return true;
else
return false;
}
return true;
}
} 
