JAVA用栈实现四则运算(转后缀表达式计算)
改进了以下,用了数组,多位数也可以运算正确了.解释都在注解里了
package Leetcode;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Calculation {
static Stack<Character> op=new Stack<>();//记住,栈里面只存符号,数字是直接输出的
public static String[] Suffix(String str){
char arr[]=str.toCharArray();//化为字符数组
String out[]=new String[str.length()];//后缀式数组,长度稳妥
boolean flag=false;//多位数判断
int index=0;//数组下标
for(int i=0;i<arr.length;i++){
char ch=arr[i];
if(ch>='0'&&ch<='9'){//如果字符是数字,就直接输出
if(i==0){
out[index]=String.valueOf(ch-'0');
}
else if(flag){//如果是多位数
out[index]=out[index]+String.valueOf(ch-'0');//不管如何先加进去
}else{//头数字
index++;
out[index]=String.valueOf(ch-'0');
}
flag=true;
continue;
}
if(ch=='+'||ch=='-'){//如果为+-号,就全部取出(有条件)再放入
while(!op.empty()&&op.peek()!='('){//栈不为空(如果为空 不就直接放入了)&&顶部不为'(' 全部取出
out[++index]=String.valueOf(op.pop());//依次while全部取出,直到为空或者为'('
}
op.push(ch);//取完记得放入
flag=false;
continue;
}
if(ch=='*'||ch=='/'){//如果为乘法或者除法
while(!op.empty()&&(op.peek()=='/'||op.peek()=='*')){//乘法取出的条件是什么?1.不为空2.下面也要是乘法或者是除法才可以取出,加减法优先级不到不可取出
out[++index]=String.valueOf(op.pop());
}
op.push(ch);
flag=false;
continue;
}
if(ch=='('){//如果是左括号,就直接放入
op.push(ch);//直接放入
flag=false;
continue;
}
if(ch==')'){//如果是右括号
while(op.peek()!='('){//顶部不为(就一直取
out[++index]=String.valueOf(op.pop());
}
//取完不用放入,相反还要除去(
op.pop();
flag=false;
continue;
}
}
//for完之后,可能栈里面还有值,直接全部取出
while(!op.empty()){
out[++index]=String.valueOf(op.pop());
}
return out;
}
static Stack<Double> oo=new Stack<>();//计算后缀,只存数字
public static Double Sum(String out[]){
for(int i=0;i<out.length;i++){
String str=out[i];
if(out[i]==null)
break;
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);//用正则表达式判断str是否为数字
if(isNum.matches()){//如果为数字
oo.push(Double.parseDouble(str));
continue;
}
double num1,num2;
switch (str) {
case "+":
num1=oo.pop();//取出
num2=oo.pop();//取出
oo.push(num2+num1);//放入
break;
case "-":
num1=oo.pop();//第一次取出
num2=oo.pop();//第二次取出
oo.push(num2-num1);//注意是后出减先出
break;
case "*":
num1=oo.pop();//取出
num2=oo.pop();//取出
oo.push(num2*num1);//放入
break;
case "/":
num1=oo.pop();//第一次取出
num2=oo.pop();//第二次取出
oo.push(num2/num1);//注意是后出除先出
break;
}
}
double sum=oo.pop();
return sum;
}
public static void main(String[] args) {
System.out.println(Sum(Suffix("9+(3-1)*3+10/2")));
}
}