中缀表达式转逆波兰表达式,计算器也可

package A;

import java.util.ArrayList;
//此程序你可以验算你的逆波兰表达式有没有写对
//4*5-8+60+8/2=4 5 * 8 - 60 + 8 2 / +
//其实逆波兰表达式并不难,也是由我们常用的中缀表达式转换来的,仔细写一下就知道了
public class JosePhu {
public static void main(String[] args) {
ArrayStack arrayStack = new ArrayStack();
String expression="1+((2+3)*4)-5";
//将表达式放到String数组里面
ArrayList<String> infixExpressionList=arrayStack.toInfixExpressionList(expression);
System.out.println("中缀表达式="+infixExpressionList);
//换成逆波兰表达式
ArrayList<String> suffixExpressionList=arrayStack.parseSuffixExpressionList(infixExpressionList);
System.out.println("逆波兰表达式="+suffixExpressionList);
//计算结果
System.out.println("结果:"+arrayStack.calculate(suffixExpressionList));
}
}

package A;

import java.util.ArrayList;
import java.util.Stack;

public class ArrayStack {
private int ADD=1;
private int SUB=1;
private int MUL=2;
private int DIV=2;
//将suffixExpression分割,然后放入动态数组
public ArrayList<String> getListString(String suffixExpression){
//将suffixExpression按空格分割成一段一段的数组,类型是String
//其实这里分割的很巧妙,不论是10,还是1000,反正都是作为数组中的一个值,就解决了那种只检测一位的问题
String[] spilt=suffixExpression.split(" ");
ArrayList<String> list=new ArrayList<>();
//有for的地方必定是循环,所以这里是对spilt进行循环,把它给加到list里面去
for (String ele:spilt){
list.add(ele);
}
return list;
}
//对逆波兰表达式进行计算
public int calculate(ArrayList<String> ls){
Stack<String> stack=new Stack<>();
for (String item:ls){
//正则表达式,如果item匹配的是多位数,是一个类似于123的数字,那么直接入栈
//"\\s+"匹配任何空白字符,包括空格、制表符、换页符等等,等价于[ \f\n\r\t\v]
//你可以这样:return s.replaceAll("\\s+","");将字符串中空白字符去掉
if (item.matches("\\d+")){
stack.push(item);
}else {
//不知你发现没有,它只设置了一个栈,而且只有数字才入栈
int num2=Integer.parseInt(stack.pop());
int num1=Integer.parseInt(stack.pop());
int res=0;
if (item.equals("+")){
res=num1+num2;
}else if (item.equals("-")){
res=num1-num2;
}else if (item.equals("*")){
res=num1*num2;
}else if (item.equals("/")){
res=num1/num2;
}else {
throw new RuntimeException("运算符有误");
}
stack.push(""+res);
}
}
return Integer.parseInt(stack.pop());
}
public ArrayList<String> toInfixExpressionList(String s){
ArrayList<String> ls=new ArrayList<>();
int i=0;
String str;
char c;
do {
/*if ((c=s.charAt(i))<48||(c=s.charAt(i))>57){
ls.add(""+c);//原来将char加入到String要加上这个:""+
i++;
}else {
str="";
while (i<s.length()&&(c=s.charAt(i))>=48&&(c=s.charAt(i))<=57){
str=str+c;
i++;
}
ls.add(str);
}*/
c=s.charAt(i);
ls.add(""+c);
i++;
}while (i<s.length());
return ls;
}
//此方法真的牛
public ArrayList<String> parseSuffixExpressionList(ArrayList<String> ls){
Stack<String> s1=new Stack<>();//符号栈
//因为考虑到,此栈只需入栈,而且后面需要从壶底输出,所以用数组方便一点
ArrayList<String> s2=new ArrayList<>();//数字栈
for (String item:ls){
if (item.matches("\\d+")){
s2.add(item);
}else if (item.equals("(")){
s1.push(item);
}else if (item.equals(")")){
while (!s1.peek().equals("(")){
s2.add(s1.pop());
}
s1.pop();
}else {
while (s1.size()!=0&&getValue(s1.peek())>=getValue(item)){
s2.add(s1.pop());
}
s1.push(item);
}
}
while (s1.size()!=0){
s2.add(s1.pop());
}
return s2;
}
public int getValue(String operation){
int result=0;
switch (operation){
case "+":
result=ADD;
break;
case "-":
result=SUB;
break;
case "*":
result=MUL;
break;
case "/":
result=DIV;
break;
default:
result=-1;//将")"的值设为-1
break;
}
return result;
}
}

 

posted @ 2021-07-27 15:53  朱在春  阅读(87)  评论(0编辑  收藏  举报