算术表达式求解java实现

一.处理的对象

算术表达式(Arithmetical Expression):一个任意给定的由+、-、*、/、(、)以及阿拉伯数字组成的字符串,把"0.123456789"还有负号作为操作数,把"(+-*/)"作为操作符。例如:(12.89+(-9))*2.65/(-3)。

二.处理的方法

1.定义两个栈,一个操作符(operator)栈,一个操作数(operand)栈。

2.判断表达式是否合法,合法进入3,否则进入4。

①字符合法性检验,每个字符必须是算术表达式中要求的字符;

②括号匹配检验,包括个数是否匹配,以及位置是否正确合法。

"("前不能有操作数,后不能有操作符;")"前不能有操作符,后不能有操作数。

③小数点合法性检验,其前其后都要有数字。

④操作符合法性检验,操作符两边要有操作数。

⑤区分"-"是操作数中的负号还是操作符中的减号。

3.解析表达式并运算。

①遇到操作符确定不是负号,从上一个操作符位置开始截取字符串,把结果转换成double型数据,放入操作数栈;

②遇到操作符。

如果是"+-",从操作数栈中取出两个操作数,从操作符栈中取出一个操作符做运算,把运算的结果放入操作数栈中,同时把当前遇到的操作符放入操作符栈中。

如果是"*/",判断操作符中的最后一个操作符,如果是"*/",从操作数栈中取出两个操作数,从操作符栈中取出一个操作符做运算,把运算的结果放入操作数栈中,同时把当前遇到的操作符放入操作符栈中;如果是"+-",把当前操作符放入操作符栈中。

③对于一个含有括号的算术表达式,只需从最内层括号部分开始次做②的运算,直到操作符栈空结束。

4.得到结果信息,处理完毕。

三.JAVA实现

Code:
  1. package ttwork.expression;   
  2.   
  3. import java.util.Stack;   
  4.   
  5. public class ArithExpression {   
  6.     private String expression;     //定义算术表达式的域   
  7.     private String errorMessage;   //定义错误信息域   
  8.     private String result = "0";   //定义表达式的结果   
  9.   
  10.     public ArithExpression() {   
  11.         expression = null;   
  12.         errorMessage = null;   
  13.     }   
  14.     public ArithExpression(String str) {   
  15.         expression = str;   
  16.     }   
  17.        
  18.     public boolean isDigit(char ch) {         //判断表达式中的字符是否为数字?   
  19.         String digits = "0123456789";   
  20.         if(digits.indexOf(ch) == -1) {   
  21.             return false;   
  22.         } else {   
  23.             return true;   
  24.         }   
  25.     }   
  26.     public boolean isOperator(char ch) {      //判断表达式中的字符是否为操作符?   
  27.         String operators = "+-*/";   
  28.         if(operators.indexOf(ch) == -1) {   
  29.             return false;   
  30.         } else {   
  31.             return true;   
  32.         }   
  33.     }   
  34.     public boolean isParenthese(char ch) {    //判断表达式中的字符是否为小括号?   
  35.         String parentheses = "()";   
  36.         if(parentheses.indexOf(ch) == -1) {   
  37.             return false;   
  38.         } else {   
  39.             return true;   
  40.         }   
  41.     }   
  42.     private int charCount(char ch) {          //表达式中某个字符的个数   
  43.         int count = 0;   
  44.         for(int i=0; i<expression.length(); i++) {   
  45.             if(expression.charAt(i) == ch) {   
  46.                 count++;   
  47.             }   
  48.         }   
  49.         return count;   
  50.     }   
  51.     public boolean isLegal() {                //判断表达式是否合法?   
  52.         //检验表达式中是否有不合法的字符   
  53.         if(expression.length() == 0) {   
  54.             errorMessage = "表达式为空……";   
  55.             return false;   
  56.         }   
  57.         for(int i=0; i<expression.length(); i++) {   
  58.             if("0123456789.+-*/()".indexOf(expression.charAt(i))== -1) {   
  59.                 errorMessage = "表达式中第"+(i+1)+"个字符不合表达式的要求!请仔细检查……";   
  60.                 return false;   
  61.             }   
  62.         }   
  63.         //检验表达式中括号个数是否匹配   
  64.         if(charCount('(') != charCount(')')) {   
  65.             errorMessage = "请检查括号个数是否匹配!";   
  66.             return false;   
  67.         }   
  68.         //检验第一个字符和最后一个字符是否合法   
  69.         if("-0123456789(".indexOf(expression.charAt(0))==-1 ||   
  70.             "0123456789)".indexOf(expression.charAt(expression.length()-1))==-1){   
  71.             errorMessage = "请检查第一个字符或者最后一个字符是否合法!";   
  72.             return false;   
  73.         }   
  74.         //检查剩余字符是否合法   
  75.         for(int j=1; j<expression.length()-1; j++) {   
  76.             //对括号的要求   
  77.             if(expression.charAt(j) == '(') {   
  78.                 if("+-*/(".indexOf(expression.charAt(j-1))==-1 ||   
  79.                     "0123456789(-".indexOf(expression.charAt(j+1))==-1) {   
  80.                     errorMessage = "表达式中第"+(j+1)+"个字符'('处有错误,请仔细检查……";   
  81.                     return false;   
  82.                 }   
  83.             }   
  84.             if(expression.charAt(j) == ')') {   
  85.                 if("+-*/)".indexOf(expression.charAt(j+1))==-1 ||   
  86.                     "0123456789)".indexOf(expression.charAt(j-1))==-1) {   
  87.                     errorMessage = "表达式中第"+(j+1)+"个字符')'处有错误,请仔细检查……";   
  88.                     return false;   
  89.                 }   
  90.             }   
  91.             //操作数两边必须为数字   
  92.             if(isOperator(expression.charAt(j))) {   
  93.                 //对于‘-’来说可以是操作符也可以是负号   
  94.                 if(expression.charAt(j) == '-'    
  95.                     && ("0123456789)(".indexOf((expression.charAt(j-1)))!=-1 || "".indexOf((expression.charAt(j-1)))!=-1)   
  96.                     && "0123456789(".indexOf(expression.charAt(j+1))!=-1) {   
  97.                     continue;   
  98.                 } else if(expression.charAt(j) == '/' && expression.charAt(j+1) == '0') {   
  99.                     errorMessage = "被除数为0是不符合算术运算的……";   
  100.                     return false;   
  101.                 } else {   
  102.                     if("0123456789)".indexOf((expression.charAt(j-1)))==-1    
  103.                             || "0123456789(".indexOf(expression.charAt(j+1))==-1) {   
  104.                         errorMessage = "表达式中第"+(j+1)+"个字符处有错误,请仔细检查……";   
  105.                         return false;   
  106.                     }   
  107.                 }   
  108.             }   
  109.             //对小数点的要求   
  110.             if(expression.charAt(j) == '.') {   
  111.                 if(!isDigit(expression.charAt(j-1)) || !isDigit(expression.charAt(j+1))) {   
  112.                     errorMessage = "表达式中第"+(j+1)+"个字符'.'处有错误,请仔细检查……";   
  113.                     return false;   
  114.                 }   
  115.             }   
  116.         }   
  117.         return true;   
  118.     }   
  119.     public String getErrorMessage() {         //得到表达式的错误信息   
  120.         return errorMessage;   
  121.     }   
  122.     private String value(String str) {        //计算最简表达式的值,不含括号,私有方法   
  123.         Stack<Double> staOperand = new Stack<Double>();   
  124.         Stack<String> staOperator = new Stack<String>();   
  125.         Double res = new Double(0);   
  126.         int j = 0;   
  127.         if(str.charAt(0) == '-') {   
  128.             str = "0"+str;   
  129.         }   
  130.         for(int i=0; i<str.length(); i++) {   
  131.             if(i == str.length()-1) {   
  132.                 res = new Double(Double.parseDouble(str.substring(j, i+1)));   
  133.                 staOperand.push(res);   
  134.                 while(!staOperator.empty()) {   
  135.                     double a = staOperand.pop();   
  136.                     double b = staOperand.pop();   
  137.                     switch(staOperator.pop().charAt(0)) {   
  138.                         case '+': res = new Double(a+b); break;   
  139.                         case '-': res = new Double(b-a); break;   
  140.                         case '*': res = new Double(a*b); break;   
  141.                         case '/': res = new Double(b/a); break;   
  142.                     }   
  143.                     staOperand.push(res);                  
  144.                 }   
  145.                 break;   
  146.             }   
  147.             if("+-*/".indexOf(str.charAt(i)) != -1) {   
  148.                 if(str.charAt(i) == '-') {   
  149.                     if("+-*/".indexOf(str.charAt(i-1)) != -1) {   
  150.                         j = i;   
  151.                         continue;   
  152.                     }   
  153.                 }   
  154.                 staOperand.push(new Double(Double.parseDouble(str.substring(j, i))));   
  155.                 j = i+1;   
  156.                    
  157.                 if(staOperator.empty()) {   
  158.                     staOperator.push(str.charAt(i)+"");   
  159.                 } else {   
  160.                     if("*/".indexOf(str.charAt(i))!=-1 && "+-".indexOf(staOperator.peek())!=-1) {   
  161.                         staOperator.push(str.charAt(i)+"");   
  162.                     }   
  163.                     if("*/".indexOf(str.charAt(i))!=-1 && "*/".indexOf(staOperator.peek())!=-1) {   
  164.                         double a = staOperand.pop();   
  165.                         double b = staOperand.pop();   
  166.                         if(staOperator.pop().equals("*")) {   
  167.                             res = new Double(a*b);   
  168.                         } else {   
  169.                             res = new Double(b/a);   
  170.                         }   
  171.                         staOperator.push(str.charAt(i)+"");   
  172.                         staOperand.push(res);   
  173.                     }   
  174.                     if("+-".indexOf(str.charAt(i))!=-1){   
  175.                         double a = staOperand.pop();   
  176.                         double b = staOperand.pop();   
  177.                         switch(staOperator.pop().charAt(0)) {   
  178.                             case '+': res = new Double(a+b); break;   
  179.                             case '-': res = new Double(b-a); break;   
  180.                             case '*': res = new Double(a*b); break;   
  181.                             case '/': res = new Double(b/a); break;   
  182.                         }   
  183.                         staOperator.push(str.charAt(i)+"");   
  184.                         staOperand.push(res);   
  185.                     }   
  186.                 }                  
  187.             }   
  188.         }   
  189.         return res+"";   
  190.     }   
  191.     public String getResult() {               //对表达式进行运算并输出其结果   
  192.         String strTemp = expression;   
  193.         String resTemp = "0";  //存放临时结果   
  194.         int left = 0;   
  195.         int right = 0;   
  196.         while(strTemp.indexOf(')') != -1) {   
  197.             right = strTemp.indexOf(')');   
  198.             left = strTemp.substring(0, right).lastIndexOf('(');   
  199.             resTemp = value(strTemp.substring(left+1, right));   
  200.             strTemp = strTemp.substring(0, left) + resTemp +strTemp.substring(right+1);   
  201.         }   
  202.         result = value(strTemp);   
  203.         return result;   
  204.     }   
  205.     public String toString() {                //重写toString方法   
  206.         return expression;   
  207.     }   
  208. }  

上面代码实现乘除混合运算时还有错误,暂时未能解决……

你可能感兴趣的:(算术表达式求解java实现)