题目如下:
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.
Example 1:
Input: “3+2*2”
Output: 7
Example 2:
Input: " 3/2 "
Output: 1
Example 3:
Input: " 3+5 / 2 "
Output: 5
就是设计一个简单的四则运算
这道题的关键是用栈的解决 例如3+5/2 我们遍历这个字符串 第一个是数字3 我们把它存到栈中 再遍历到‘+’ 就证明是加法运算 所以我们要把+后面的数字也放入栈中 也就是 5 放入栈中 再遍历到’/’ 这个时候我们就要计算5/2了 因为‘/’和’*‘的优先级是最高的 可以直接运算就行 所以我们就要将’/‘前面的数字除’/'后面的数字 得到他前面的数字只需pop栈中的第一个元素即可 以此类推 直到结束
以上就是算法的核心思想 但是问题难在哪呢 我们遍历的时候 看到数字 没问题 我们就将数字记录下来 但是我们遍历到一个运算符号的时候 我们需要判断它的类型 如果是乘号和除号 我们就需要计算这个字符的前一个数字和后面一个数字 我们还只是遍历到这个字符 对她后面一个元素我们还不知道 所以我们也无法计算 那怎么办呢 很简单 我们记录这个符号的前一个符号 然后用前一个符号来计算两个数字 例如 我们遍历到 3+5/2 的‘+’时 他的前一个符号是空的 所以我们不做操作 只把3压入栈中 当我们遍历到/的时候 我们就可以判断前一个运算符 如果是+或者减 就把数字压入栈中 如果是乘或除 就计算结果再压入栈中(此时我们已经可以计算出结果了 因为我们已经遍历到乘和除后面的一个运算符了 所以乘法的两个对象都已经知道了) 例如3+5/2+5 当我们遍历到最后一个加号时 我们已经知道了/的前一个元素(栈中的第一个元素)和后一个元素 (当前储存的num值) 这样就可以解决啦 但是 我们这个例子 3+5/2 我们如果 只看运算符的前一个运算符的话 我们最后一个运算符就不会被执行 所以 我们需要人为的给字符串后面加上一个符号(任意,只要不是数字即可) 然后我们再把栈中的元素累加即可得到结果。
代码如下:
public int calculate(String s) {
if(s == null) {
return 0;
}
LinkedList<Integer> list = new LinkedList();
char[] c = new char[s.length()+1];
for(int i=0;i<c.length-1;i++) {
c[i] = s.charAt(i);
}
c[c.length-1] = '+';
int num = 0;
int r = 0;
char pre = 'X';
for(int i=0;i<c.length;i++) {
if(c[i] == ' ') {
continue;
}
if(c[i] >= '0' && c[i] <= '9') {
num = num*10 + (c[i] - '0');
}else {
switch (pre) {
case '+':
list.push(num);
break;
case '-':
list.push(num *(-1));
break;
case '*':
r = (list.pop() * num);
list.push(r);
break;
case '/':
r = (list.pop() / num);
list.push(r);
break;
default:
list.push(num);
break;
}
pre = c[i];
num = 0;
}
}
int n = 0;
while(list.size() != 0) {
n += list.pop();
}
return n;
}