Guest User

Untitled

a guest
May 7th, 2018
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.82 KB | None | 0 0
  1. import java.util.HashMap;
  2. import java.lang.Double;
  3.  
  4. /************************************************************************
  5.  * <i>Mathematic expression evaluator.</i> Supports the following functions:
  6.  * +, -, *, /, ^, %, cos, sin, tan, acos, asin, atan, sqrt, sqr, log, min, max, ceil, floor, abs, neg, rndr.<br>
  7.  * When the getValue() is called, a Double object is returned. If it returns null, an error occured.<p>
  8.  * <pre>
  9.  * Sample:
  10.  * MathEvaluator m = new MathEvaluator("-5-6/(-2) + sqr(15+x)");
  11.  * m.addVariable("x", 15.1d);
  12.  * System.out.println( m.getValue() );
  13.  * </pre>
  14.  * @version 1.1
  15.  * @author  The-Son LAI, <a href="mailto:Lts@writeme.com">Lts@writeme.com</a>
  16.  * @date     April 2001
  17.  ************************************************************************/
  18. public class MathEvaluator
  19. {
  20.     protected static    Operator[]  operators   = null;
  21.     private             Node        node        = null;
  22.     private             String      expression  = null;
  23.     private             HashMap     variables   = new HashMap();
  24.  
  25.     /***
  26.      * Main. To run the program in command line.
  27.      * Usage: java MathEvaluator.main [your math expression]
  28.      */
  29.     public static void main(String[] args)
  30.     {
  31.         if ( args == null || args.length != 1)
  32.         {
  33.             System.err.println("Math Expression Evaluator by The-Son LAI Lts@writeme.com C(2001):");
  34.             System.err.println("Usage: java MathEvaluator.main [your math expression]");
  35.             System.exit(0);
  36.         }
  37.  
  38.         try
  39.         {
  40.             MathEvaluator m = new MathEvaluator(args[0]);
  41.             System.out.println( m.getValue() );
  42.         }
  43.         catch (Exception e)
  44.         {
  45.             e.printStackTrace();
  46.         }
  47.     }
  48.  
  49.     /***
  50.      * creates an empty MathEvaluator. You need to use setExpression(String s) to assign a math expression string to it.
  51.      */
  52.     public MathEvaluator()
  53.     {
  54.         init();
  55.     }
  56.  
  57.     /***
  58.      * creates a MathEvaluator and assign the math expression string.
  59.      */
  60.     public MathEvaluator(String s)
  61.     {
  62.         init();
  63.         setExpression(s);
  64.     }
  65.  
  66.     private void init()
  67.     {
  68.         if ( operators == null ) initializeOperators();
  69.     }
  70.  
  71.     /***
  72.      * adds a variable and its value in the MathEvaluator
  73.      */
  74.     public void addVariable(String v, double val)
  75.     {
  76.         addVariable(v, new Double(val));
  77.     }
  78.  
  79.     /***
  80.      * adds a variable and its value in the MathEvaluator
  81.      */
  82.     public void addVariable(String v, Double val)
  83.     {
  84.         variables.put(v, val);
  85.     }
  86.  
  87.     /***
  88.      * sets the expression
  89.      */
  90.     public void setExpression(String s)
  91.     {
  92.         expression = s;
  93.     }
  94.  
  95.     /***
  96.      * resets the evaluator
  97.      */
  98.     public void reset()
  99.     {
  100.         node        = null;
  101.         expression  = null;
  102.         variables   = new HashMap();
  103.     }
  104.  
  105.     /***
  106.      * trace the binary tree for debug
  107.      */
  108.     public void trace()
  109.     {
  110.         try
  111.         {
  112.             node = new Node(expression);
  113.             node.trace();
  114.         }
  115.         catch (Exception e)
  116.         {
  117.             e.printStackTrace();
  118.         }
  119.     }
  120.  
  121.     /***
  122.      * evaluates and returns the value of the expression
  123.      */
  124.     public Double getValue()
  125.     {
  126.         if (expression == null) return null;
  127.  
  128.         try
  129.         {
  130.             node = new Node(expression);
  131.             return evaluate(node);
  132.         }
  133.         catch (Exception e)
  134.         {
  135.             e.printStackTrace();
  136.             return null;
  137.         }
  138.     }
  139.  
  140.     private static Double evaluate(Node n)
  141.     {
  142.         if ( n.hasOperator() && n.hasChild() )
  143.         {
  144.             if ( n.getOperator().getType() == 1 )
  145.                 n.setValue ( evaluateExpression( n.getOperator(), evaluate( n.getLeft() ), null ) );
  146.             else if ( n.getOperator().getType() == 2 )
  147.                 n.setValue( evaluateExpression( n.getOperator(), evaluate( n.getLeft() ), evaluate( n.getRight() ) ) );
  148.         }
  149.         return n.getValue();
  150.     }
  151.  
  152.     private static Double evaluateExpression(Operator o, Double f1, Double f2)
  153.     {
  154.         String op   = o.getOperator();
  155.         Double res  = null;
  156.  
  157.         if       ( "+".equals(op) )     res = new Double( f1.doubleValue() + f2.doubleValue() );
  158.         else if  ( "-".equals(op) )     res = new Double( f1.doubleValue() - f2.doubleValue() );
  159.         else if  ( "*".equals(op) )     res = new Double( f1.doubleValue() * f2.doubleValue() );
  160.         else if  ( "/".equals(op) )     res = new Double( f1.doubleValue() / f2.doubleValue() );
  161.         else if  ( "^".equals(op) )     res = new Double( Math.pow(f1.doubleValue(), f2.doubleValue()) );
  162.         else if  ( "%".equals(op) )     res = new Double( f1.doubleValue() % f2.doubleValue() );
  163.         else if  ( "&".equals(op) )     res = new Double( f1.doubleValue() + f2.doubleValue() ); // todo
  164.         else if  ( "|".equals(op) )     res = new Double( f1.doubleValue() + f2.doubleValue() ); // todo
  165.         else if  ( "cos".equals(op) )   res = new Double( Math.cos(f1.doubleValue()) );
  166.         else if  ( "sin".equals(op) )   res = new Double( Math.sin(f1.doubleValue()) );
  167.         else if  ( "tan".equals(op) )   res = new Double( Math.tan(f1.doubleValue()) );
  168.         else if  ( "acos".equals(op) )  res = new Double( Math.acos(f1.doubleValue()) );
  169.         else if  ( "asin".equals(op) )  res = new Double( Math.asin(f1.doubleValue()) );
  170.         else if  ( "atan".equals(op) )  res = new Double( Math.atan(f1.doubleValue()) );
  171.         else if  ( "sqr".equals(op) )   res = new Double( f1.doubleValue() * f1.doubleValue() );
  172.         else if  ( "sqrt".equals(op) )  res = new Double( Math.sqrt(f1.doubleValue()) );
  173.         else if  ( "log".equals(op) )   res = new Double( Math.log(f1.doubleValue()) );
  174.         else if  ( "ln".equals(op) )    res = new Double( Math.log(f1.doubleValue()) / Math.log(Math.E));
  175.         else if  ( "min".equals(op) )   res = new Double( Math.min(f1.doubleValue(), f2.doubleValue()) );
  176.         else if  ( "max".equals(op) )   res = new Double( Math.max(f1.doubleValue(), f2.doubleValue()) );
  177.         else if  ( "exp".equals(op) )   res = new Double( Math.exp(f1.doubleValue()) );
  178.         else if  ( "floor".equals(op) ) res = new Double( Math.floor(f1.doubleValue()) );
  179.         else if  ( "ceil".equals(op) )  res = new Double( Math.ceil(f1.doubleValue()) );
  180.         else if  ( "abs".equals(op) )   res = new Double( Math.abs(f1.doubleValue()) );
  181.         else if  ( "neg".equals(op) )   res = new Double( - f1.doubleValue() );
  182.         else if  ( "rnd".equals(op) )   res = new Double( Math.random() * f1.doubleValue() );
  183.  
  184.         return res;
  185.     }
  186.  
  187.     private void initializeOperators()
  188.     {
  189.         operators     = new Operator[26];
  190.         operators[0]  = new Operator("+"    , 2, 0);
  191.         operators[1]  = new Operator("-"    , 2, 0);
  192.         operators[2]  = new Operator("*"    , 2, 10);
  193.         operators[3]  = new Operator("/"    , 2, 10);
  194.         operators[4]  = new Operator("^"    , 2, 10);
  195.         operators[5]  = new Operator("%"    , 2, 10);
  196.         operators[6]  = new Operator("&"    , 2, 0);
  197.         operators[7]  = new Operator("|"    , 2, 0);
  198.         operators[8]  = new Operator("cos"  , 1, 20);
  199.         operators[9]  = new Operator("sin"  , 1, 20);
  200.         operators[10] = new Operator("tan"  , 1, 20);
  201.         operators[11] = new Operator("acos" , 1, 20);
  202.         operators[12] = new Operator("asin" , 1, 20);
  203.         operators[13] = new Operator("atan" , 1, 20);
  204.         operators[14] = new Operator("sqrt" , 1, 20);
  205.         operators[15] = new Operator("sqr"  , 1, 20);
  206.         operators[16] = new Operator("log"  , 1, 20);
  207.         operators[17] = new Operator("ln"   , 1, 20);
  208.         operators[18] = new Operator("min"  , 2, 0);
  209.         operators[19] = new Operator("max"  , 2, 0);
  210.         operators[20] = new Operator("exp"  , 1, 20);
  211.         operators[21] = new Operator("floor", 1, 20);
  212.         operators[22] = new Operator("ceil" , 1, 20);
  213.         operators[23] = new Operator("abs"  , 1, 20);
  214.         operators[24] = new Operator("neg"  , 1, 20);
  215.         operators[25] = new Operator("rnd"  , 1, 20);
  216.     }
  217.  
  218.     /***
  219.      * gets the variable's value that was assigned previously
  220.      */
  221.     public Double getVariable(String s)
  222.     {
  223.         return (Double) variables.get(s);
  224.     }
  225.  
  226.     private Double getDouble(String s)
  227.     {
  228.         if ( s == null ) return null;
  229.  
  230.         Double res = null;
  231.         try
  232.         {
  233.             res = new Double(Double.parseDouble(s));
  234.         }
  235.         catch(Exception e)
  236.         {
  237.             return getVariable(s);
  238.         }
  239.  
  240.         return res;
  241.     }
  242.  
  243.     protected Operator[] getOperators()
  244.     {
  245.         return operators;
  246.     }
  247.  
  248.     protected class Operator
  249.     {
  250.         private String op;
  251.         private int type;
  252.         private int priority;
  253.  
  254.         public Operator(String o, int t, int p)
  255.         {
  256.             op = o;
  257.             type = t;
  258.             priority = p;
  259.         }
  260.  
  261.         public String getOperator()
  262.         {
  263.             return op;
  264.         }
  265.  
  266.         public void setOperator(String o)
  267.         {
  268.             op = o;
  269.         }
  270.  
  271.         public int getType()
  272.         {
  273.             return type;
  274.         }
  275.  
  276.         public int getPriority()
  277.         {
  278.             return priority;
  279.         }
  280.     }
  281.  
  282.     protected class Node
  283.     {
  284.         public String   nString     = null;
  285.         public Operator nOperator   = null;
  286.         public Node     nLeft       = null;
  287.         public Node     nRight      = null;
  288.         public Node     nParent     = null;
  289.         public int      nLevel      = 0;
  290.         public Double   nValue      = null;
  291.  
  292.         public Node(String s) throws Exception
  293.         {
  294.             init(null, s, 0);
  295.         }
  296.  
  297.         public Node(Node parent, String s, int level) throws Exception
  298.         {
  299.             init(parent, s, level);
  300.         }
  301.  
  302.         private void init(Node parent, String s, int level) throws Exception
  303.         {
  304.             s = removeIllegalCharacters(s);
  305.             s = removeBrackets(s);
  306.             s = addZero(s);
  307.             if ( checkBrackets(s) != 0 ) throw new Exception("Wrong number of brackets in [" + s + "]");
  308.  
  309.             nParent             = parent;
  310.             nString             = s;
  311.             nValue              = getDouble(s);
  312.             nLevel              = level;
  313.             int sLength         = s.length();
  314.             int inBrackets      = 0;
  315.             int startOperator   = 0;
  316.  
  317.             for (int i=0; i<sLength; i++)
  318.             {
  319.                 if ( s.charAt(i) == '(' )
  320.                     inBrackets++;
  321.                 else if ( s.charAt(i) == ')' )
  322.                     inBrackets--;
  323.                 else
  324.                 {
  325.                     // the expression must be at "root" level
  326.                     if ( inBrackets == 0 )
  327.                     {
  328.                         Operator o = getOperator(nString,i);
  329.                         if ( o != null )
  330.                         {
  331.                             // if first operator or lower priority operator
  332.                             if ( nOperator == null || nOperator.getPriority() >= o.getPriority() )
  333.                             {
  334.                                 nOperator       = o;
  335.                                 startOperator   = i;
  336.                             }
  337.                         }
  338.                     }
  339.                 }
  340.             }
  341.  
  342.             if ( nOperator != null )
  343.             {
  344.                 // one operand, should always be at the beginning
  345.                 if ( startOperator==0 && nOperator.getType() == 1 )
  346.                 {
  347.                     // the brackets must be ok
  348.                     if ( checkBrackets( s.substring( nOperator.getOperator().length() ) ) == 0 )
  349.                     {
  350.                         nLeft  = new Node( this, s.substring( nOperator.getOperator().length() ) , nLevel + 1);
  351.                         nRight = null;
  352.                         return;
  353.                     }
  354.                     else
  355.                         throw new Exception("Error during parsing... missing brackets in [" + s + "]");
  356.                 }
  357.                 // two operands
  358.                 else if ( startOperator > 0 && nOperator.getType() == 2 )
  359.                 {
  360.                     nOperator = nOperator;
  361.                     nLeft   = new Node( this, s.substring(0,  startOperator), nLevel + 1 );
  362.                     nRight  = new Node( this, s.substring(startOperator + nOperator.getOperator().length()), nLevel + 1);
  363.                 }
  364.             }
  365.         }
  366.  
  367.         private Operator getOperator(String s, int start)
  368.         {
  369.             Operator[] operators = getOperators();
  370.             String temp = s.substring(start);
  371.             temp = getNextWord(temp);
  372.             for (int i=0; i<operators.length; i++)
  373.             {
  374.                 if ( temp.startsWith(operators[i].getOperator()) )
  375.                     return operators[i];
  376.             }
  377.             return null;
  378.         }
  379.  
  380.         private String getNextWord(String s)
  381.         {
  382.             int sLength = s.length();
  383.             for (int i=1; i<sLength; i++)
  384.             {
  385.                 char c = s.charAt(i);
  386.                 if ( (c > 'z' || c < 'a') && (c > '9' || c < '0') )
  387.                     return s.substring(0, i);
  388.             }
  389.             return s;
  390.         }
  391.  
  392.         /***
  393.          * checks if there is any missing brackets
  394.          * @return true if s is valid
  395.          */
  396.         protected int checkBrackets(String s)
  397.         {
  398.             int sLength     = s.length();
  399.             int inBracket   = 0;
  400.  
  401.             for (int i=0; i<sLength; i++)
  402.             {
  403.                 if      ( s.charAt(i) == '(' && inBracket >= 0 )
  404.                     inBracket++;
  405.                 else if ( s.charAt(i) == ')' )
  406.                     inBracket--;
  407.             }
  408.  
  409.             return inBracket;
  410.         }
  411.  
  412.         /***
  413.          * returns a string that doesnt start with a + or a -
  414.          */
  415.         protected String addZero(String s)
  416.         {
  417.             if ( s.startsWith("+") || s.startsWith("-") )
  418.             {
  419.                 int sLength     = s.length();
  420.                 for (int i=0; i<sLength; i++)
  421.                 {
  422.                     if ( getOperator(s, i) != null )
  423.                         return "0" + s;
  424.                 }
  425.             }
  426.  
  427.             return s;
  428.         }
  429.  
  430.         /***
  431.          * displays the tree of the expression
  432.          */
  433.         public void trace()
  434.         {
  435.             String op = getOperator() == null ? " " : getOperator().getOperator() ;
  436.             _D( op + " : " + getString() );
  437.             if ( this.hasChild() )
  438.             {
  439.                 if ( hasLeft() )
  440.                     getLeft().trace();
  441.                 if ( hasRight() )
  442.                     getRight().trace();
  443.             }
  444.         }
  445.  
  446.         protected boolean hasChild()
  447.         {
  448.             return ( nLeft != null || nRight != null );
  449.         }
  450.  
  451.         protected boolean hasOperator()
  452.         {
  453.             return ( nOperator != null );
  454.         }
  455.  
  456.         protected boolean hasLeft()
  457.         {
  458.             return ( nLeft != null );
  459.         }
  460.  
  461.         protected Node getLeft()
  462.         {
  463.             return nLeft;
  464.         }
  465.  
  466.         protected boolean hasRight()
  467.         {
  468.             return ( nRight != null );
  469.         }
  470.  
  471.         protected Node getRight()
  472.         {
  473.             return nRight;
  474.         }
  475.  
  476.         protected Operator getOperator()
  477.         {
  478.             return nOperator;
  479.         }
  480.  
  481.         protected int getLevel()
  482.         {
  483.             return nLevel;
  484.         }
  485.  
  486.         protected Double getValue()
  487.         {
  488.             return nValue;
  489.         }
  490.  
  491.         protected void setValue(Double f)
  492.         {
  493.             nValue = f;
  494.         }
  495.  
  496.         protected String getString()
  497.         {
  498.             return nString;
  499.         }
  500.  
  501.         /***
  502.          * Removes spaces, tabs and brackets at the begining
  503.          */
  504.         public String removeBrackets(String s)
  505.         {
  506.             String res = s;
  507.             if ( s.length() > 2 && res.startsWith("(") && res.endsWith(")") && checkBrackets(s.substring(1,s.length()-1)) == 0 )
  508.             {
  509.                 res = res.substring(1, res.length()-1 );
  510.             }
  511.             if ( res != s )
  512.                 return removeBrackets(res);
  513.             else
  514.                return res;
  515.         }
  516.  
  517.         /***
  518.          * Removes illegal characters
  519.          */
  520.         public String removeIllegalCharacters(String s)
  521.         {
  522.             char[] illegalCharacters = { ' ' };
  523.             String res = s;
  524.  
  525.             for ( int j=0; j<illegalCharacters.length; j++)
  526.             {
  527.                 int i = res.lastIndexOf(illegalCharacters[j], res.length());
  528.                 while ( i != -1 )
  529.                 {
  530.                     String temp = res;
  531.                     res = temp.substring(0,i);
  532.                     res += temp.substring(i + 1);
  533.                     i = res.lastIndexOf(illegalCharacters[j], s.length());
  534.                 }
  535.             }
  536.             return res;
  537.         }
  538.  
  539.         protected void _D(String s)
  540.         {
  541.             String nbSpaces = "";
  542.             for (int i=0; i<nLevel; i++) nbSpaces += "  ";
  543.             System.out.println(nbSpaces + "|" + s);
  544.         }
  545.     }
  546.  
  547.     protected static void _D(String s)
  548.     {
  549.         System.err.println(s);
  550.     }
  551. }
Add Comment
Please, Sign In to add comment