• 【JAVA】通过公式字符串表达式计算值,网上的一种方法



    public class Test {
     
     public static void main(String[] args) {
     
      SimpleCalculator s=new SimpleCalculator();
     String methord="80*(1+0.5)"; //test
      double d=s.evaluate(methord );
      System.out.println(d);
     }
    }
     
     
     
     
    import java.util.Scanner;
    import java.util.Stack;
    public class SimpleCalculator {
     
     
     /**
      * Evaluate an arithmetic expression, and return the result as a double.
      *
      * @param input
      * the expression to evaluate.
      * @return the evaluated result.
      */
     public double evaluate(String input) {
      initialize();
      this.scanner = new Scanner(input);
      this.scanner
        .useDelimiter("\s+|(?=[.0-9])(?<![.0-9])|(?![.0-9])(?<=[.0-9])|(?![.0-9])(?<![.0-9])");
      Token currentToken = nextToken();
      Token t = null;
      while (null != currentToken) {
       switch (currentToken.getKind()) {
       case NUMBER:
        // Simply push number tokens onto the evaluation stack.
        this.eval.push(currentToken.getValue());
        break;
       case LPAREN:
        // Simply push left parenthesis tokens onto the operator stack.
        this.ops.push(currentToken);
        break;
       case RPAREN:
        // Until a left parenthesis pops off the operator stack, keep
        // poping operators and execute them.
        // If the stack becomes empty without a matching left
        // parenthesis,
        // the expression must have syntax errors.
        for (t = this.ops.pop(); TokenKind.LPAREN != t.getKind(); t = this.ops
          .pop()) {
         if (ops.empty())
          throw new Error("Syntax Error: unmatched parenthesis");
         doOperation(t);
        }
        break;
       default:
        // For binary arithmetic operators, keep poping operators whose
        // binding power
        // is less or equal to the current token's and execute them;
        // after that push
        // the current token onto the operator stack.
        if (!ops.empty()) {
         for (t = this.ops.pop(); currentToken.getKind()
           .getBindingPower() < t.getKind().getBindingPower(); t = this.ops
           .pop()) {
          doOperation(t);
          if (this.ops.empty()) {
           t = null;
           break;
          }
         }
        }
        if (null != t)
         ops.push(t);
        ops.push(currentToken);
        break;
       }
       // reinitialize
       currentToken = nextToken();
      }
      // execute remaining operators on stack
      while (!ops.empty()) {
       t = this.ops.pop();
       doOperation(t);
      }
      // the result is on the top of evaluation stack,
      // pop it off and return the result.
      return this.eval.pop();
     }
     /*
      * Initialize the evaluation and operator stacks.
      */
     private void initialize() {
      if (null == this.eval)
       this.eval = new Stack<Double>();
      if (null == this.ops)
       this.ops = new Stack<Token>();
      this.eval.clear();
      this.ops.clear();
     }
     /*
      * Return the next token from the input expression. The token returned will
      * be associated with its numeric value, if and only if the token is a
      * number.
      */
     private Token nextToken() {
      Token t = null;
      if (this.scanner.hasNextDouble()) {
       t = new Token(TokenKind.NUMBER, this.scanner.nextDouble());
      } else if (this.scanner.hasNext()) {
       String s = this.scanner.next("[-+*/()]");
       if ("+".equals(s)) {
        t = new Token(TokenKind.ADD);
       } else if ("-".equals(s)) {
        t = new Token(TokenKind.SUBTRACT);
       } else if ("*".equals(s)) {
        t = new Token(TokenKind.MULTIPLY);
       } else if ("/".equals(s)) {
        t = new Token(TokenKind.DIVIDE);
       } else if ("(".equals(s)) {
        t = new Token(TokenKind.LPAREN);
       } else if (")".equals(s)) {
        t = new Token(TokenKind.RPAREN);
       }
      }
      return t;
     }
     /*
      * Execute a binary arithmetic operation. Pop the top two values off the
      * evaluation stack, do the operation, and then push the result back onto
      * the evaluation stack.
      */
     private void doOperation(Token t) {
      double y = this.eval.pop();
      double x = this.eval.pop();
      double temp = t.getKind().doOperation(x, y);
      this.eval.push(temp);
     }
     /*
      * Tokenizer for the input expression.
      */
     private Scanner scanner;
     /*
      * Evaluation stack.
      */
     private Stack<Double> eval;
     /*
      * Operator stack, for converting infix expression to postfix expression.
      */
     private Stack<Token> ops;
     public static void main(String[] args) {
      if (args.length < 1) {
       System.err.println("Usage: java SimpleCalculator <expression>");
       System.exit(1);
      }
      SimpleCalculator calc = new SimpleCalculator();
      double result = calc.evaluate(args[0]);
      System.out.println(result);
     }
    }
    enum TokenKind {
     // operators
     ADD(1) {
      public double doOperation(double x, double y) {
       return x + y;
      }
     },
     SUBTRACT(2) {
      public double doOperation(double x, double y) {
       return x - y;
      }
     },
     MULTIPLY(3) {
      public double doOperation(double x, double y) {
       return x * y;
      }
     },
     DIVIDE(4) {
      public double doOperation(double x, double y) {
       return x / y;
      }
     },
     // punctuation
     LPAREN(0), RPAREN(0),
     // number
     NUMBER(0);
     TokenKind(int bindingPower) {
      this.bindingPower = bindingPower;
     }
     public int getBindingPower() {
      return this.bindingPower;
     }
     public double doOperation(double x, double y) {
      return Double.NaN; // dummy, operation not supported
     }
     private int bindingPower;
    }
    class Token {
     public Token(TokenKind kind) {
      this(kind, Double.NaN);
     }
     public Token(TokenKind kind, double value) {
      this.kind = kind;
      this.value = value;
     }
     public TokenKind getKind() {
      return this.kind;
     }
     public double getValue() {
      return this.value;
     }
     private TokenKind kind;
     private double value;
    }
  • 相关阅读:
    数据库性能优化之冗余字段的作用
    SQL里面的排序语句desc和ASC有什么区别
    Mybatis@options注解属性useGeneratedKeys,keyProperty,keyColumn的使用
    关于resultType与parameterType的基本使用和区别
    阿里云Centos7的部署springboot后mysql中文问号乱码
    LINUX下启动/停止/重启MYSQL
    CondenseNet:可学习分组卷积,原作对DenseNet的轻量化改造 | CVPR 2018
    MnasNet:经典轻量级神经网络搜索方法 | CVPR 2019
    MobileNetV1/V2/V3简述 | 轻量级网络
    ShuffleNetV1/V2简述 | 轻量级网络
  • 原文地址:https://www.cnblogs.com/liuyongcn/p/3567805.html
Copyright © 2020-2023  润新知