中缀表达式:也就是人们最熟悉的公式计算思路
后缀表达式:计算机进行公式计算的表达式
后面一部分是将后缀表达式进行计算。
package com.midtosuffer;
import java.util.ArrayList;
import java.util.Stack;
public class MidtoSuffer //中缀表达式转后缀表达式
{
public static void main(String[] args) {
String str = "1 + ( ( 2 + 3 ) * 4 ) - 5";
ArrayList<String> array = trans(str);//将字符串数组转化为字符串链表
ArrayList<String> arr = MidtoSuffer(array);
cal(arr);
}
public static ArrayList<String> trans(String s)//转换:1.先把字符串转换成字符串数组,然后存储到一个ArrayLiST表中
{
ArrayList<String> array = new ArrayList<>();//定义一个链表,用于存储字符
String[] split = s.split(" ");
for (int i = 0; i < split.length; i++) //将字符串数组存储到一个链表中,方便后序操作
{
array.add(split[i]);
}
for (int i = 0; i < array.size(); i++) {
System.out.print(array.get(i) + " ");
}
System.out.println();
return array;
}
public static ArrayList<String> MidtoSuffer(ArrayList<String> array) {
Stack<String> s1 = new Stack<String>();//用于存储运算符号
ArrayList<String> s2 = new ArrayList<String>();//用于存储数字
for (String itm : array) {
if (itm.matches("\\d+"))//正则表达式,用来判断字符串是否为数字
{
s2.add(itm);
} else if (itm.charAt(0) == '(') {
s1.push(itm);
} else if (itm.charAt(0) == ')') { //此时弹出的是)
while (true) {
s2.add(s1.pop());
if (s1.peek().charAt(0) == '(') {
s1.pop();
break;
}
}
} else//最为重要的一步,如果扫描到字符优先级小于s1栈顶的运算符,则将s1中的字符压入到s2中,反复执行这个过程,直到要传入的字符大于s1中字符串优先级
{
while (s1.size() != 0 && priority(s1.peek()) >= priority(itm)) {
s2.add(s1.pop());
}
s1.push(itm);
}
}
while (s1.size()!=0)
s2.add(s1.pop());
}
return s2;
}
public static int priority(String s1)//将二个运算符的优先级进行比较
{
if (s1.charAt(0) == '+' || s1.charAt(0) == '-')
return 0;
else if (s1.charAt(0) == '*' || s1.charAt(0) == '/')
return 1;
else
return -1;
}
public static void cal(ArrayList<String> arr)//对后缀表达式进行计算
{ //123+4*+5- 1 + ( ( 2 + 3 ) * 4 ) - 5
Stack<String> stack = new Stack<>();//用来存储数字
for(String str:arr)
{
if(str.matches("\\d+")) {
stack.push(str);//将数字压入栈中
}
else
{
int num1=Integer.valueOf(stack.pop());//从栈弹出二个数字进行运算
int num2=Integer.valueOf(stack.pop());
switch (str.charAt(0)){
case '+':
stack.push(String.valueOf(num1+num2));
break;
case '-':
stack.push(String.valueOf(num2-num1));
break;
case '*':
stack.push(String.valueOf(num1*num2));
break;
case '/':
stack.push(String.valueOf(num1/num2));
break;
}
}
}
System.out.println(stack.pop());
}
}