题目:
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +
, -
, *
, /
operators and empty spaces . The integer division should truncate toward zero.
You may assume that the given expression is always valid.
思路:重点无疑是stack。然后想到了在数据结构里面看到的中缀表达式转后缀表达式,然后用stack计算最终结果
代码:
public int calculate(String s) {
int re=0;
if(s==null||s.length()==0)
return re;
s=s.trim();
s = MidToAfter(s);
return Compute(s);
}
//计算后缀表达式
public int Compute(String s){
Stack<Integer> stack = new Stack<>();
char[]chs = s.toCharArray();
for(char ch : chs ){
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){
int num2 = stack.pop();
int num1 = stack.pop();
int numRe= 0;
switch(ch){
case '+':
numRe=num1+num2;
break;
case '-':
numRe = num1 - num2;
break;
case '*':
numRe = num1 * num2;
break;
case '/':
numRe = num1 / num2;
break;
}
stack.push(numRe);
}else{
stack.push(ch-'0');
}
}
return stack.pop();
}
//讲中缀表达式转为后缀表达式 1 + 2 -> 1 2 +
public String MidToAfter(String s){
char [] chs = s.toCharArray();
StringBuffer re = new StringBuffer() ;
Stack<Character> stack = new Stack<>();
for(char ch : chs){
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){
if(stack.isEmpty()||prio(ch,stack.peek())==1){
//优先级高,入栈
stack.push(ch);
}else{
//优先级一样或者低
re.append(stack.pop());
stack.push(ch);
}
}else{
re.append(ch);
}
}
while(!stack.isEmpty()){
re.append(stack.pop());
}
return re.toString();
}
//优先级 -1:op1<op2 0:op1=op2 1:op1>op2
public int prio(char op1,char op2){
if (op1 == '+' || op1 == '-')
{
if (op2 == '*' || op2 == '/')
{
return -1;
}
else
{
return 0;
}
}
if (op1 == '*' || op1 == '/')
{
if (op2 == '+' || op2 == '-')
{
return 1;
}
else
{
return 0;
}
}
return 0;
}
本以为可以A了,但是发现,这么些只适用于10以内的!不开心!
借鉴大神的思路:
首先肯定是得用stack的,读取数据放入stack中,但是stack是加法堆。意思是如果遇到减法,就把后面的操作数的负数加入stack中;如果遇到乘法或者除法,则取出栈顶数,计算*/ 把结果入栈。最后累加stack中的元素即为最终结果。
代码:
public int calculate(String s) {
if(s == null || s.length() == 0) {
return 0;
}
Stack<Integer> stack = new Stack<>();
char sign = '+';
int num =0;
char [] chs = s.toCharArray();
for(int i=0;i<=s.length();i++){//主意不是i<s.length() 这样做是为了处理最后一个数字和运算符
char ch;
if(i==s.length()){
ch='e';//sentinel
}else
ch = chs[i];
if(ch==' ')
continue;
if(Character.isDigit(ch)){
num=(num*10+(ch-'0'));
}else{
if(sign=='+')
stack.push(0+num);
else if(sign=='-')
stack.push(0-num);
else if(sign=='*')
stack.push(stack.pop()*num);
else if(sign=='/')
stack.push(stack.pop()/num);
num=0;
sign=ch;
}
}
int re=0;
for(int i:stack)
re+=i;
return re;
}