227.基本计算器II
解题思路:使用辅助栈
package leadcode;
import java.util.Deque;
import java.util.LinkedList;
/**
* @author : icehill
* @description : 基本计算器II
* 给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
* 整数除法仅保留整数部分。
* 示例 1:
* 输入:s = "3+2*2"
* 输出:7
* 示例 2:
* 输入:s = " 3/2 "
* 输出:1
* 示例 3:
* 输入:s = " 3+5 / 2 "
* 输出:5
* 提示:
* 1 <= s.length <= 3 * 10^5
* s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
* s 表示一个 有效表达式
* 表达式中的所有整数都是非负整数,且在范围 [0, 2^31 - 1] 内
* 题目数据保证答案是一个 32-bit 整数
* <p>
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/basic-calculator-ii
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* 解题思路:
* 好像没啥好说的,就是利用栈或者双端队列来存储数字,再根据优先级来运算
* 我的做法是先将字符串解析出来,符号跟数字分别存放到两个栈里面,然后再通过一轮遍历计算
* 官方做法就比较简洁,栈里面值保留加法(减法转成+负数),遇到乘除直接计算后再
* @date : 2021-05-05
*/
public class Solution227 {
public static void main(String[] args) {
Solution227 solution227 = new Solution227();
System.out.println(solution227.calculate("3+2*2"));
System.out.println(solution227.calculate("1+1+1"));
}
public int calculateTwo(String s) {
Deque<Integer> stack = new LinkedList<Integer>();
char preSign = '+';
int num = 0;
int n = s.length();
for (int i = 0; i < n; ++i) {
if (Character.isDigit(s.charAt(i))) {
num = num * 10 + s.charAt(i) - '0';
}
if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
switch (preSign) {
case '+':
stack.push(num);
break;
case '-':
stack.push(-num);
break;
case '*':
stack.push(stack.pop() * num);
break;
default:
stack.push(stack.pop() / num);
}
preSign = s.charAt(i);
num = 0;
}
}
int ans = 0;
while (!stack.isEmpty()) {
ans += stack.pop();
}
return ans;
}
/**
* 计算器
*
* @param s
* @return
*/
public int calculate(String s) {
Deque<Character> symbol = new LinkedList<>();
Deque<Integer> nums = new LinkedList<>();
int i = 0;
while (i < s.length()) {
if (s.charAt(i) == ' ') {
i++;
continue;
}
if (s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '*' || s.charAt(i) == '/') {
symbol.add(s.charAt(i));
i++;
continue;
}
i = getNum(s, i, nums);
}
//每次取出一个符号,并取出两个数字
while (!symbol.isEmpty()) {
char c = symbol.pop();
int a;
int b;
//乘除直接计算,加减且下一位符号非空需要看下一位符号
if (c == '*' || c == '/' || symbol.isEmpty()) {
a = nums.pop();
b = nums.pop();
nums.addFirst(doCalculate(a, b, c));
} else {
char nextC = symbol.getFirst();
if (nextC == '*' || nextC == '/') {
int temp = nums.pop();
a = nums.pop();
b = nums.pop();
symbol.pop();
nums.addFirst(doCalculate(a, b, nextC));
nums.addFirst(temp);
symbol.addFirst(c);
} else {
a = nums.pop();
b = nums.pop();
nums.addFirst(doCalculate(a, b, c));
}
}
}
return nums.pop();
}
private int doCalculate(int a, int b, char c) {
if (c == '+') {
return a + b;
} else if (c == '-') {
return a - b;
} else if (c == '*') {
return a * b;
} else {
return a / b;
}
}
private int getNum(String s, int start, Deque<Integer> nums) {
int i = start;
//去除前导空格
while (i < s.length() && s.charAt(i) == ' ') {
i++;
continue;
}
int num = 0;
while (i < s.length()) {
if (!Character.isDigit(s.charAt(i))) {
break;
}
num = num * 10 + s.charAt(i) - '0';
i++;
}
nums.add(num);
return i;
}
}