用Java实现中缀表达式转后缀表达式
中缀表达式转后缀表达式
后缀表达式 后缀表达式又称逆波兰表达式,明显的特点是:逆波兰表达式中没有括号,计算时将操作符之前的第一个数作为右操作数,第二个数作为左操作数,进行计算,得到的值继续放入逆波兰表达式中。 但日常生活中我们总是习惯于写中缀表达式,所以需要先将中缀表达式转为后缀表达式。
规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。 简单图解后缀表达式 opStack用于存储操作符,suffixList用于存储后缀表达式字符。将操作符按照操作顺序及操作符优先级写入操作符栈,然后将整个表达式按后缀表达式特点依次存入线性表中
代码实现
public String infixToSuffix(String infixExpression){ //定义一个操作符栈 ArrayStack<String> opStack = new ArrayStack<>(); //定义一个存后缀字符的线性表 ArrayList<String> suffixList = new ArrayList<>(); //格式化表达式 infixExpression = insertBlanks(infixEXpression); String[] tokens = infixExpression.split(" "); System.out.println(Arrays.toString(tokens)); for(String token : tokens){ if(token.length() == 0){ continue; } if(isOperator(token)){ //如果是操作符 while(true){ //栈空 或 栈顶是( 直接进; 当前操作符的优先级 > 栈顶操作符的优先级 直接进 if(opStack.isEmpty() || "(".equals(opStack.peek()) || priority(token) > poiority(opStack.peek())){ opStack.push(token); break; } //如果栈不为空 且 栈顶不是( 且栈顶操作符优先级 >= 当前操作符优先级 suffixList.add(opStack.pop()); } }else if (isNumber(token)){ //如果是数字 suffixList.add(token); }else if ("(".equals(token)){ //如果是“(” opStack.push(token); }else if (")".equals(token)){ //如果是“)” while (true){ if ("(".equals(opStack.peek())){ opStack.pop(); break; }else{ suffixList.add(opStack.pop()); } } }else { throw new IllegalArgumentException("wrong identify"+ token); } }while (!opStack.isEmpty()){ suffixList.add(opStack.pop()); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < suffixList.size; i++) { sb.append(suffixList.get(i)+" "); } return sb.toString(); } private int priority(Sting token){ if("*".equals(token) || "/".equals(tokens)){ return 1; }else if("+".equals(token) || "-".equals(tokens)){ return 0; }else{ return -1; } } private boolean isOperator(String token){ return "+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token); } private boolean isNumber(String token){ return token.matches("\d+"); // \d+匹配的是表示多个数字 } private String insertBlanks(String expression){ StringBuilder sb = new StringBuilder(); //遍历表达式 for(int i = 0; i < expression.length(); i++){ char c = expression.charAt(i); //如果是符号,则在符号前后增加空格 if(c == ( || c == ) || c == + || c == - || c == * || c == /){ sb.append(" "); sb.append(c); sb.append(" "); }else { //如果遇到数字 则原封不动添加在sb sb.append(c); } } return sb.toString(); } }
运行结果:
下一篇:
面试知识点(数据结构)