工具类(包含表达式切割方法,和实现方法)
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遇到运算符时,比较其与s1栈顶运算符的优先级:
// 1)如果s1为空,或栈顶运算符为左括号“)”,则直接将此运算符入栈;
// 2)否则,若优先级比栈顶运算符的高或者相等,也将运算符压入stackSym;
// 3)否则,将s1栈顶的运算符弹出并压入到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 = list.size()-1; i >= 0; 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 (!stackNum.empty()){
bacExpression.append(stackNum.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("1+(2+3)*4+5");
System.out.println("1+(2+3)*4+5 转为前缀式:" + s0);
System.out.println("=============================================");
}
}
测试结果