中缀表达式(10+20/2*3)/2+8,其转换成后缀表达式则为10 20 2 / 3 * + 2 / 8 +
转换过程需要用到栈,具体过程如下:
1)当遇到操作数,我们就直接将其输出。
2)当遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)当遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。
注意,左括号只弹出并不输出。
package Stack;
import ListInterfcae_list.ArrayList;
/*
中缀转后缀
*/
public class InfixToSuffix {
public static void main(String[] args){
String infixExpression = "(10+20/2*3)/2+8";
String suffixExpression = infixToSuffix(infixExpression);
System.out.println(suffixExpression);
}
public static String infixToSuffix(String infixExpression) {
ArrayStack<String> opStack = new ArrayStack<String>();
ArrayList<String> suffixList = new ArrayList<>();
infixExpression = insertBlanks(infixExpression);
String[] tokens = infixExpression.split(" ");
for (String token : tokens) {
//过滤空串
if (token.length() == 0) {
continue;
}
//如果是操作符
if (isOperator(token) ) {
while (true){
if (opStack.isEmpty() || opStack.peek().equals("(") || priority(opStack.peek()) < priority(token)) {
opStack.push(token);
break;
}
suffixList.add(opStack.pop());
}
}else if (token.equals("(")){
opStack.push(token);
}else if (token.equals(")")){
while (!opStack.peek().equals("(")) {
suffixList.add(opStack.pop());
}
opStack.pop();
}else if (isNumber(token)){
suffixList.add(token);
}else {
throw new IllegalArgumentException("wrong char :" + infixExpression);
}
}
while (!opStack.isEmpty()){
suffixList.add(opStack.pop());
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < suffixList.size(); i++) {
sb.append(suffixList.get(i));
sb.append(' ');
}
return sb.toString();
}
private static boolean isNumber(String token) {
return token.matches("\\d+");
}
private static int priority(String token) {
if (token.equals("+") || token.equals("-")) {
return 0;
}
if (token.equals("*") || token.equals("/")) {
return 1;
}
return -1;
}
private static boolean isOperator(String token) {
return token.equals("+") || token.equals("-") || token.equals("*") ||token.equals("/");
}
private static String insertBlanks(String infixExpression) {
StringBuilder sb = new StringBuilder();
char c ;
for (int i = 0; i < infixExpression.length(); i++) {
c = infixExpression.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*'
|| c == '/'){
sb.append(" ");
sb.append(c);
sb.append(" ");
}else{
sb.append(c);
}
}
return sb.toString();
}
}
后缀计算器:
对于后缀表达式,我们只需要一个栈即可,当遇到数字时直接进栈,当遇到操作符时直接弹栈两个数字进行运算,再将结果进栈
package Stack;
public class SuffixCalculator {
public static void main(String[] args) {
String infixExpression = "(10+20/2*3)/2+8";
String expression = InfixToSuffix.infixToSuffix(infixExpression);
System.out.println(expression);
ArrayStack<Integer> stack = new ArrayStack<Integer>();
String[] tokens = expression.split(" ");
for (String token :tokens){
//如果是数字直接进栈
if (isNumber(token)){
stack.push(new Integer(token));
}
if (isOperator(token)){
processionExpression(stack,token);
}
}
System.out.println(stack.pop());
}
private static boolean isOperator(String token) {
return token.equals("+") || token.equals("-") || token.equals("*") ||token.equals("/");
}
private static boolean isNumber(String token) {
return token.matches("\\d+"); // \\d+ 表示匹配的是多个数字
}
private static void processionExpression(ArrayStack<Integer> stack, String token) {
int num1 = stack.pop();
int num2 = stack.pop();
switch (token) {
case "+":
stack.push(num2 + num1);
break;
case "-":
stack.push(num2 - num1);
break;
case "*":
stack.push(num2 * num1);
break;
case "/":
stack.push(num2 / num1);
break;
}
}
}