给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。
表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。
示例 1:
输入: "3+2*2"
输出: 7
示例 2:
输入: " 3/2 "
输出: 1
示例 3:
输入: " 3+5 / 2 "
输出: 5
说明:
你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/calculator-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路1:对应代码行Line78-115
1、用正则表达式去除空格
2、因为个人原因一时间想不到很好的办法去处理多位数字,于是偷懒再次用正则抽取出所有数字。
3、根据操作符,+-操作数数字入栈,*/操作数取出栈顶数字算出结果入栈
4、出栈加和得出结果
解题思路2:对应代码行Line18-76
对上面的方法做了一个小小的优化。
1、用正则表达式去除空格
2、依次取数字,并根据数字长度取操作符
3、根据操作符,+-操作数数字入栈,*/操作数取出栈顶数字算出结果入栈
4、出栈加和得出结果
综上,其实都算不上是很棒的解题,但是比较容易想到的思路。思路2取数字的时候,其实是多读了一位操作符,如果能够合理利用应该 也能提升点滴性能。
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class SolutionCalu {
public static void main(String[] args) {
SolutionCalu cal = new SolutionCalu();
String s = " 13 +2*3+6-4*2 +1 ";
int res = cal.calculate(s);
System.out.println("res:"+res);
s = " 13+5 / 2";
res = cal.calculate(s);
System.out.println("res:"+res);
}
public int calculate(String s) {
Stack<Integer> values = new Stack<Integer>();
s=s.replaceAll(" ", "");
int index = 0;
int firstRes[] = getNextNum(s,index);
values.push(firstRes[0]);
System.out.println("0:"+values.peek());
index += firstRes[1];
System.out.println("0:"+index);
while(index < s.length()) {
char tmp = s.charAt(index);
switch(tmp) {
case '+':
firstRes = getNextNum(s,++index);
values.push(firstRes[0]);
index += firstRes[1];
break;
case '-':
firstRes = getNextNum(s,++index);
values.push(-firstRes[0]);
index += firstRes[1];
break;
case '*':
firstRes = getNextNum(s,++index);
values.push(values.pop() * firstRes[0]);
index += firstRes[1];
break;
case '/':
firstRes = getNextNum(s,++index);
values.push(values.pop() / firstRes[0]);
index += firstRes[1];
break;
default :
break;
}
}
int result = 0;
while(!values.isEmpty()) {
result += values.pop();
}
return result;
}
private int[] getNextNum(String s, int startIndex) {
int[] result = new int[2];
int endIndex = s.length();
for(int i= startIndex;i<s.length();i++) {
if(!Character.isDigit(s.charAt(i))) {
endIndex = i;
break;
}
}
result[0] = Integer.parseInt(s.substring(startIndex, endIndex));
result[1] = endIndex - startIndex;
return result;
}
public int calculate2(String s) {
Stack<Integer> values = new Stack<Integer>();
s=s.replaceAll(" ", "");
List<Integer> list = new ArrayList<>();
for(String tmp : s.split("\\+|-|\\*|/")) {
list.add(Integer.parseInt(tmp));
}
int index = 0;
values.push(list.get(index++));
for(int i=0;i<s.length();i++) {
char tmp = s.charAt(i);
switch(tmp) {
case '+':
values.push(list.get(index++));
break;
case '-':
values.push(-list.get(index++));
break;
case '*':
values.push(values.pop() * list.get(index++));
break;
case '/':
values.push(values.pop() / list.get(index++));
break;
default :
break;
}
}
int result = 0;
while(!values.isEmpty()) {
result += values.pop();
}
return result;
}
}