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
Note: Do not use the eval
built-in
library function.
Step1:把字符串s按照()+-进行分割成字符串数组;
Step2:新建一个stack存放目前计算的值;
Step3:依次遍历字符串数组中的每个字符串;如果遇到的是左括号(或+或-或数字则压栈,
如果是右括号)则把弹栈直到遇到(,把括号内的值计算后再压栈;
Step4:把栈内的元素进行运算。
第三步相当于去括号,第四步计算去掉括号之后的值。
/**
* 计算表达式的值。
* Step1:把字符串s按照()+-进行分割成字符串数组;
* Step2:新建一个stack存放目前计算的值;
* Step3:依次遍历字符串数组中的每个字符串;如果遇到的是左括号(或+或-或数字则压栈,
* 如果是右括号)则把弹栈直到遇到(,把括号内的值计算后再压栈;
* Step4:把栈内的元素进行运算。
*
* 第三步相当于去括号,第四步计算去掉括号之后的值。
*/
public int calculate(String s) {
Stack stack = new Stack<String>();
ArrayList<String> list = new ArrayList<String>();
int sLen = s.length();
int index = 0;
StringBuilder sb;
/*查分字符串为数字和括号+-,比如1 + 1拆分为1,+,1*/
while(index<sLen){
char c = s.charAt(index);
/*如果遇到的是空格,则忽略*/
if(c == ' '){
index++;
continue;
}
/*如果遇到的是符号,则入list*/
if(c == '+' || c == '(' || c == ')' || c == '-' ){
list.add(s.substring(index,index+1));
index++;
}else{//如果是数字则把当前的这数字取完
sb = new StringBuilder();
while(index<sLen && s.charAt(index)!='+' && s.charAt(index)!='-'
&& s.charAt(index)!='(' && s.charAt(index)!=')'
&& s.charAt(index)!=' '){
sb.append(s.charAt(index));
index++;
}
list.add(sb.toString());
}
}
int len = list.size();
/* 如果list只有一个元素说明字符串s只有一个数字,直接返回即可 */
if (len == 1) {
return Integer.valueOf(list.get(0));
}
/*第一遍相当于把表达式中间的括号都去掉*/
int i = 0;
stack.add(list.get(0));// 先把第一个元素入栈
i++;
while (i < len) {
String temp = list.get(i);
if (temp.equals(")")) { // 如果是右括号)则把弹栈直到遇到(,把括号内的值计算后再压栈;
EntreParentesis(stack);
} else {
stack.add(temp);
}
i++;
}
/*然后计算栈内表达式的值*/
EntreParentesis(stack);
return Integer.valueOf((String) stack.pop());
}
/*
* 计算栈顶的一个括号内的值,现在栈顶的若干个元素如(5-2+3+4,
* 这个方法完成的工作就是通过把若干个栈顶元素(左括号之前包括左括号)弹栈计算得出10,然后把10压入栈
*/
private void EntreParentesis(Stack<String> stack) {
int right;// 右操作数
int left;// 左操作数
/*把(5-2+3+4依次弹栈,然后再压入tempStack中*/
Stack<String> tempStack = new Stack<String>();
while (!stack.isEmpty() && !stack.peek().equals("(")) {
tempStack.add(stack.pop());
}
if (!stack.isEmpty()) {//如果栈不为空,则需要弹出"(",然后把结果压栈;如果栈为空,比如计算前栈内只有5这一个数字
stack.pop();
}
/*计算tempStack中表达式的值*/
String val = (String) tempStack.pop();
right = Integer.valueOf(val);
while (!tempStack.isEmpty() ) {
String oper = tempStack.pop();
left = Integer.valueOf(tempStack.pop());
if (oper.equals("+")) {
right = left + right;
} else {
right = right - left;
}
}
stack.add(right + "");
}