Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open (
and closing parentheses )
, the plus +
or minus sign -
, non-negative integers and empty spaces .
You may assume that the given expression is always valid.
Some examples:
"1 + 1" = 2 " 2-1 + 2 " = 3 "(1+(4+5+2)-3)+(6+8)" = 23下面是将中序表达式转成后缀表达式的方法,自己写的:
public class Solution {
public boolean isNum(char c){
return c != '(' && c != ')' && c != '+' && c != '-' && c != ' ';
}
public boolean highPriority(char insatck, char next){
//the problem involve '+' '-' and '()'
if(next == '('){
return true;
}
return false;
}
public void calcul(Stack<Integer> nums,char operate){
int num;
if(operate == '+'){
num = nums.pop() + nums.pop();
nums.push(num);
}
if(operate == '-'){
int num1 = nums.pop();
int num2 = nums.pop();
num = num2 - num1;
nums.push(num);
}
}
public int calculate(String s) {
int len = s.length();
char[] str = s.toCharArray();
int i = 0;
Stack<Character> stack = new Stack<Character>();
Stack<Integer> nums = new Stack<Integer>();
while(i < len){
while(i<len && str[i] == ' '){
++i;
}
if(i < len && !isNum(str[i])){
if(stack.isEmpty()){
stack.push(str[i]);
}else{
if(highPriority(stack.peek(),str[i])){
stack.push(str[i]);
}else{
// calculate first then push operate into stack
char operate;
if(str[i] != ')'){
while(!stack.isEmpty() && !highPriority(stack.peek(),str[i]) && stack.peek() != '('){
operate = stack.pop();
calcul(nums,operate);
}
stack.push(str[i]);
}else{
while(!stack.isEmpty() && (operate = stack.pop()) != '('){
calcul(nums,operate);
}
}
}
}
++i;
}
if(i < len && isNum(str[i])){
int num = 0;
while(i < len && isNum(str[i])){
num = (str[i] - '0') + num * 10;
++i;
}
nums.push(num);
}
}
while(!stack.isEmpty()){
calcul(nums,stack.pop());
}
return nums.pop();
}
}
提交完后看了下discuss,发现其他奇怪解法,有个将字符串逆序的方法,奇淫巧技!!!链接:
https://discuss.leetcode.com/topic/15816/iterative-java-solution-with-stack
又重写了这题,感觉上次代码写的不清楚,这次加了注释
public class Solution {
int get_num(char[] str, int i, int[] len){
int next_num = 0;
while(i < str.length && str[i] <= '9' && str[i] >= '0'){
next_num = next_num*10 + str[i] - '0';
++len[0];
++i;
}
return next_num;
}
public int calculate(String s) {
Stack<Character> operate = new Stack<Character>();
Stack<Integer> nums = new Stack<Integer>();
char[] str = s.toCharArray();
for(int i = 0; i < str.length; ++i){
if(str[i] == ' ') continue;
//只有'('有更高优先级,高优先级或者operate为空时直接压入堆栈
if(str[i] == '('){
operate.push(str[i]);
}
//低优先级或者相等优先级,先取operate栈顶操作符,计算得到的数值压入nums堆栈,并把新操作符压入operate,栈顶是'('例外,此时直接压入操作符
else if(str[i] == '+' || str[i] == '-'){
if((!operate.isEmpty() && operate.peek() == '(') || operate.isEmpty()){
operate.push(str[i]);
}else{
char ope = operate.pop();
int num1 = nums.pop();
int num2 = nums.pop();
if(ope == '-') nums.push(num2 - num1);
if(ope == '+') nums.push(num2 + num1);
operate.push(str[i]);
}
}
//如果新操作符')'则需先弹出operate栈顶的计算操作符计算后再把'('弹出,如果operate栈顶操作符就是'(',则不需要计算这一步骤,直接对operate栈pop
else if(str[i] == ')'){
if(operate.peek() == '('){
operate.pop();
}else{
char ope = operate.pop();
int num1 = nums.pop();
int num2 = nums.pop();
if(ope == '-') nums.push(num2 - num1);
if(ope == '+') nums.push(num2 + num1);
operate.pop();
}
}
else{
int[] len = new int[]{0};
nums.push(get_num(str, i, len));
i = i + len[0] - 1;
}
}
if(!operate.isEmpty()){
char ope = operate.pop();
int num1 = nums.pop();
int num2 = nums.pop();
if(ope == '-') nums.push(num2 - num1);
if(ope == '+') nums.push(num2 + num1);
}
return nums.pop();
}
}