工具类(包含表达式切割方法,和实现方法)
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;
/**
* className:Util
*
* @author:zjl
* @version:0.1
* @date:2020/8/419:53
* @since:jdk1.8
*/
public class Util {
/**
* 分割表达式
* @param expression
* @return
*/
public static List<String> splitExpression(String expression){
char[] chars = expression.toCharArray();
List<String> listString = new ArrayList<>();
for (int i = 0; i < chars.length; i++) {
if(Character.isDigit(chars[i])||chars[i]=='.'|| chars[i]=='-'){
StringBuilder builder = new StringBuilder();
while (true){
builder.append(chars[i]);
if((i==chars.length-1||!Character.isDigit(chars[i+1])&&chars[i+1]!='.'))
break;
i++;
}
listString.add(builder+"");
}else {
listString.add(String.valueOf(chars[i]));
}
}
return listString;
}
public static int getPriority(String symbol){
switch (symbol){
case "+" :
return 1;
// case "-" :
// return 1;
case "*" :
return 2;
case "/" :
return 2;
}
return -1;
}
// 1初始化两个栈:运算符栈stackSym 和储存中间结果的栈stackNum ;
// 2从左至右扫描中缀表达式;
// 3遇到操作数时,将其压stackNum ;
// 4遇到运算符时,比较其与stackSym 栈顶运算符的优先级:
// 1)如果stackSym 为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
// 2)否则,若优先级比栈顶运算符的高,也将运算符压入stackSym ;
// 3)否则,将stackSym 栈顶的运算符弹出并压入到stackNum 中,再次转到(4-1)与stackSym 中新的栈顶运算符相比较;
//
// 5遇到括号时:
// (1) 如果是左括号“(”,则直接压入stackSym
// (2)如果是右括号“)”,则依次弹出stackSym 栈顶的运算符,并压入stackNum ,直到遇到左括号为止,此时将这一对括号丢弃
// 6重复步骤2至5,直到表达式的最右边
// 7将stackSym 中剩余的运算符依次弹出并压入stackNum
// 8依次弹出stackNum 中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
public static String cenTranBac(String expression){
Stack<String> stackNum = new Stack<>();
Stack<String> stackSym = new Stack<>();
List<String> list = splitExpression(expression);
Pattern pattern = Pattern.compile("[1-9]\\d*.\\d*|[1-9]|0.\\d*[1-9]\\d*");
Pattern pattern0 = Pattern.compile("-([1-9]\\d*.\\d*||[1-9]0.\\d*[1-9]\\d*)");
for (int i = 0; i < list.size(); i++) {
if(!pattern.matcher(list.get(i)).matches()&&!pattern0.matcher(list.get(i)).matches()){
if(stackSym.empty()||list.get(i).equals("(")||stackSym.peek().equals("(")){
stackSym.push(list.get(i));
}else if(list.get(i).equals(")")){
while (!stackSym.peek().equals("(")){
String pop = stackSym.pop();
stackNum.push(pop);
}
stackSym.pop();
} else{
if(getPriority(list.get(i))>getPriority(stackSym.peek())){
stackSym.push(list.get(i));
}else {
while (getPriority(list.get(i))<=getPriority(stackSym.peek())){
stackNum.push(stackSym.pop());
if(stackSym.empty()||stackSym.peek().equals("("))
break;
}
stackSym.push(list.get(i));
}
}
}else {
stackNum.push(list.get(i));
}
}
while (!stackSym.empty()){
stackNum.push(stackSym.pop());
}
while (!stackNum.empty()){
stackSym.push(stackNum.pop());
}
StringBuilder bacExpression = new StringBuilder();
while (!stackSym.empty()){
bacExpression.append(stackSym.pop()+" ");
}
return bacExpression+"";
}
}
测试类
import java.util.List;
/**
* className:Test
*
* @author:zjl
* @version:0.1
* @date:2020/8/420:04
* @since:jdk1.8
*/
public class Test {
public static void main(String[] args) {
//分割表达测试
List<String> list = Util.splitExpression("3*(4+2)+8.0/2");
System.out.println("=============================================");
System.out.print("3*(4+2)+8.0/2 "+"分割后的结果:");
list.forEach(p->{
System.out.print(p+",");
});
System.out.println();
System.out.println("=============================================");
//中缀转后缀
String s = Util.cenTranBac("3*(4+2)+8.0/2");
System.out.println("3*(4+2)+8.0/2 转为后缀式:"+s);
System.out.println("=============================================");
String s0 = Util.cenTranBac("8*5/2+8-2");
System.out.println("8*5/2+8-2 转为后缀式:"+s0);
System.out.println("=============================================");
}
}
测试结果