package com.company; import java.util.Stack; public class Main { public static void main(String[] args) { // write your code here String string = "(0!+1)*2^(3!+4)-(5!-67-(10+12))"; Evaluate evaluate = new Evaluate(string); System.out.println(evaluate.result()); System.out.println("RPN:"+evaluate.getRPN()); } } class Evaluate{ private String string; private String RPN; //后缀表达式 private int n=0; public Evaluate(String string){ RPN = ""; this.string = new String(string+'\0'); } private float evaluate(){ Stack<Character> operatorStack = new Stack<Character>();//操作符栈 Stack<Float> numberStack = new Stack<Float>(); //操作数栈 operatorStack.push('\0'); //尾哨兵首先推入操作符栈中 int i=0; while (!operatorStack.empty()){ if (Character.isDigit(string.charAt(i))){ //如果是数字读取数字 i = Util.readNumber(string,numberStack,i); RPN+=(numberStack.peek()+" "); }else { switch (Util.orderBetween(operatorStack.peek(),string.charAt(i))){ //比较操作符的优先级 case '<' : { //优先级小于前一运算符则推入操作数栈中 char operator = string.charAt(i); check1(operator,numberStack.size()); //检查是否符合中綴表达式的语法 operatorStack.push(operator); i++; } break; case '=' : { operatorStack.pop(); //优先级相等则推出操作符栈 i++; } break; case '>' : { //栈顶符号的优先级更高时 出栈执行运算 char op = operatorStack.pop(); RPN += (op+" "); check2(op); if (op == '!') //一元运算符 numberStack.push(Util.calculate(numberStack.pop())); //将结果推入操作数栈中 else { //二元运算符 float number1 = numberStack.pop(); float number2 = numberStack.pop(); numberStack.push(Util.calculate(number2,op,number1));//将结果推入操作数栈中 } } break; default: System.out.println("请检查括号是否匹配以及表达式的正确性"); //语法错误 System.exit(-1); } } } return numberStack.peek();//返回结果 } private void check1(char ch,int size){ switch (ch){ case '+' : case '-' : case '*' : case '/' : case '!' : case '^' : { if ((size-n) != 1) { //每个操作即将符入栈时,应该操作数栈的规模比操作符栈中规模大一 System.out.println("不符合中綴表达式的语法"); System.exit(-1); } n++;//符号入栈时 操作符的规模加一 } break; } } private void check2(char operator){ switch (operator){ case '+' : case '-' : case '*' : case '/' : case '!' : case '^' : n--; break; //相应的操作符出栈时,操作符的规模减一 } } public float result(){ return evaluate(); } public String getRPN(){ return RPN; } } class Util { public static char[][] priorityLevel = { //栈顶运算符和当前的运算的优先级 /* |-------------- 当前运算符 --------------| */ /* + - * / ^ ! ( ) \0*/ /* | + */ {'>', '>', '<', '<', '<', '<', '<', '>', '>'}, /* | - */ {'>', '>', '<', '<', '<', '<', '<', '>', '>'}, /* | * */ {'>', '>', '>', '>', '<', '<', '<', '>', '>'}, /* 顶 / */ {'>', '>', '>', '>', '<', '<', '<', '>', '>'}, /* 运 ^ */ {'>', '>', '>', '>', '<', '<', '<', '>', '>'}, /* 算 ! */ {'>', '>', '>', '>', '>', '>', ' ', '>', '>'}, /* 符 ( */ {'<', '<', '<', '<', '<', '<', '<', '=', ' '}, /* | ) */ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, /* | \0 */ {'<', '<', '<', '<', '<', '<', '<', ' ', '='} }; public static char orderBetween(char ch1,char ch2){ return priorityLevel[getIndex(ch1)][getIndex(ch2)]; } public static int getIndex(char ch){ //取得运算符优先级的下标 switch (ch){ case '+' : return 0; case '-' : return 1; case '*' : return 2; case '/' : return 3; case '^' : return 4; case '!' : return 5; case '(' : return 6; case ')' : return 7; case '\0': return 8; default: { System.out.println("operator error1"); } } System.exit(-1); return -1; } public static float calculate(float number1, char operator, float number2) { switch (operator){ case '+' : return number1+number2; case '-' : return number1-number2; case '*' : return number1*number2; case '/' : try{ return number1/number2; } catch (Exception ex){System.out.println("被除数不能为零");} case '^' : { float temp = number1; for (int i=1; i<number2; i++) temp *= number1; return temp; } default: System.out.println("operator error2"); } System.exit(-1); return -1; } public static float calculate(float number){ //阶乘 float result = 1; for (int i=1; i<=number; i++) result *= i; return result; } public static int readNumber(String string,Stack<Float> numberStack,int i){ String number=""; while(Character.isDigit(string.charAt(i))) //读取数字 number += string.charAt(i++); numberStack.push(Float.parseFloat(number)); if (string.charAt(i) != '.') return i; //如果没有小数位 float a=1; //如果有小数位 while(Character.isDigit(string.charAt(++i))){ numberStack.push(numberStack.pop() + (Float.parseFloat(string.substring(i,i+1))*(a/=10))); } return i; } }
借鉴《《数据结构(c++语言版)》》
运行结果:2017
RPN:0.0 ! 1.0 + 2.0 3.0 ! 4.0 + ^ * 5.0 ! 67.0 - 10.0 12.0 + - -