Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.33 KB | None | 0 0
  1. package app;
  2.  
  3. import java.io.*;
  4. import java.util.*;
  5. import java.util.regex.*;
  6.  
  7. import structures.Stack;
  8.  
  9. public class Expression {
  10.  
  11.     public static String delims = " \t*+-/()[]";
  12.            
  13.     /**
  14.      * Populates the vars list with simple variables, and arrays lists with arrays
  15.      * in the expression. For every variable (simple or array), a SINGLE instance is created
  16.      * and stored, even if it appears more than once in the expression.
  17.      * At this time, values for all variables and all array items are set to
  18.      * zero - they will be loaded from a file in the loadVariableValues method.
  19.      *
  20.      * @param expr The expression
  21.      * @param vars The variables array list - already created by the caller
  22.      * @param arrays The arrays array list - already created by the caller
  23.      */
  24.     public static void
  25.     makeVariableLists(String expr, ArrayList<Variable> vars, ArrayList<Array> arrays) {
  26.         /** COMPLETE THIS METHOD **/
  27.         /** DO NOT create new vars and arrays - they are already created before being sent in
  28.          ** to this method - you just need to fill them in.
  29.          **/
  30.         System.out.println(vars+"VAR | ARR"+arrays); //vars and arrays are already created but empty///// can delete after code done
  31.        
  32.         String exprNew = expr.trim(), currentItem;
  33.        
  34.         String delims2 = " \t*+-/()";
  35.         StringTokenizer st = new StringTokenizer(exprNew,delims2);
  36.        
  37.         while(st.hasMoreTokens()){
  38.             currentItem = st.nextToken();
  39.            
  40.              if ( currentItem.contains("[") ){
  41.                     boolean duplicateA = false;
  42.                     String arrName = "";
  43.                      
  44.                     for (int j = 0; j < currentItem.length(); j ++) {
  45.                          
  46.                         if (currentItem.charAt(j)== '[') {
  47.                            
  48.                             if (arrays.size() == 0) {
  49.                                     arrays.add( new Array(arrName) );
  50.                                     arrName ="";
  51.                            
  52.                             }else if (arrays.size() != 0) {
  53.                                 for (int k = 0; k < arrays.size(); k++) {
  54.                                     if (arrays.get(k).name.equals(arrName) ) {
  55.                                         // do if dupe found
  56.                                         arrName ="";
  57.                                         duplicateA = true;
  58.                                     }
  59.                                 }
  60.                                 if (duplicateA == false) {
  61.                                     arrays.add( new Array(arrName) );
  62.                                     arrName ="";
  63.                                 }
  64.                             }
  65.                        
  66.                         }else if (Character.toString(currentItem.charAt(j)).matches("[a-zA-Z]*") ){
  67.                             arrName += currentItem.charAt(j);
  68.                         }
  69.                      }
  70.                     //after looping if arrName isn't empty, that is a variable: add to variables
  71.                     if (arrName != "") {
  72.                         vars.add( new Variable(arrName) );
  73.                     }
  74.                  
  75.              }else if ( currentItem.matches("[a-zA-Z\\]]*") ) {
  76.                  if (currentItem.contains("]")){
  77.                      currentItem = currentItem.replace("]", "");
  78.                  }
  79.                
  80.                  //set duplicate boolean to false each time a possible variable is found
  81.                  boolean duplicateV = false;
  82.                  
  83.                  //if variablelist is empty, need not worry about duplicates
  84.                  if (vars.size() == 0) {
  85.                      vars.add( new Variable(currentItem) );
  86.                      
  87.                 // if variablelist has items, check each of them with current possible variable
  88.                      // if no matches found, add current p. var into list
  89.                  }else{
  90.                      for (int k = 0; k < vars.size(); k++) {
  91.                             if (vars.get(k).name.contentEquals(currentItem) ) {
  92.                                 duplicateV = true;
  93.                             }
  94.                     }
  95.                      if(duplicateV == false) {
  96.                         vars.add(new Variable(currentItem));
  97.                     }
  98.                  }
  99.              }
  100.                      
  101.         }
  102.        
  103.         System.out.println(vars+"VAR | ARR"+arrays); // vars and arrays should now be filled/////
  104.     }
  105.    
  106.     /**
  107.      * Loads values for variables and arrays in the expression
  108.      *
  109.      * @param sc Scanner for values input
  110.      * @throws IOException If there is a problem with the input
  111.      * @param vars The variables array list, previously populated by makeVariableLists
  112.      * @param arrays The arrays array list - previously populated by makeVariableLists
  113.      */
  114.     public static void
  115.     loadVariableValues(Scanner sc, ArrayList<Variable> vars, ArrayList<Array> arrays)
  116.     throws IOException {
  117.         while (sc.hasNextLine()) {
  118.             StringTokenizer st = new StringTokenizer(sc.nextLine().trim());
  119.             int numTokens = st.countTokens();
  120.             String tok = st.nextToken();
  121.             Variable var = new Variable(tok);
  122.             Array arr = new Array(tok);
  123.             int vari = vars.indexOf(var);
  124.             int arri = arrays.indexOf(arr);
  125.             if (vari == -1 && arri == -1) {
  126.                 continue;
  127.             }
  128.             int num = Integer.parseInt(st.nextToken());
  129.             if (numTokens == 2) { // scalar symbol
  130.                 vars.get(vari).value = num;
  131.             } else { // array symbol
  132.                 arr = arrays.get(arri);
  133.                 arr.values = new int[num];
  134.                 // following are (index,val) pairs
  135.                 while (st.hasMoreTokens()) {
  136.                     tok = st.nextToken();
  137.                     StringTokenizer stt = new StringTokenizer(tok," (,)");
  138.                     int index = Integer.parseInt(stt.nextToken());
  139.                     int val = Integer.parseInt(stt.nextToken());
  140.                     arr.values[index] = val;              
  141.                 }
  142.             }
  143.         }
  144.     }
  145.    
  146.     /**
  147.      * Evaluates the expression.
  148.      *
  149.      * @param vars The variables array list, with values for all variables in the expression
  150.      * @param arrays The arrays array list, with values for all array items
  151.      * @return Result of evaluation
  152.      */
  153.     public static float
  154.     evaluate(String expr, ArrayList<Variable> vars, ArrayList<Array> arrays) {
  155.         /** COMPLETE THIS METHOD **/
  156.         double temp = 0;
  157.        
  158.         ///build arrList////////////////////////////////////////
  159.         ArrayList<String> exprArrL = buildArrayListfromString(expr,vars);
  160.            
  161.         ///replace strings w bracket ---> numbers///////////////
  162.         for (int i = 0; i < exprArrL.size() ; i++) {
  163.             if (exprArrL.get(i).contains("[")) {
  164.                 temp = convertStrInArray(exprArrL.get(i), arrays, vars);
  165.                 exprArrL.set(i,Double.toString(temp));
  166.             }
  167.         }
  168.        
  169.         ///can now evaluate/////////////////////////////////////
  170.         return (float)evaluateSAL(exprArrL, arrays, vars) ;
  171.        
  172.     }
  173.        
  174.     //createArrayListfromString self explanatory/////////////////////////////////////////////////////////////////////////////////////////////////////
  175.     private static ArrayList<String> buildArrayListfromString(String expr, ArrayList<Variable> vars) {
  176.         ArrayList<String> exprArrL = new ArrayList<>();
  177.         String currentItem = "";
  178.         int bracketcount = 0;
  179.         char currC;
  180.        
  181.         for (int i = 0; i < expr.length(); i++) {
  182.            
  183.             currC = expr.charAt(i);
  184.            
  185.             if (currC == '[') {
  186.                 bracketcount++;
  187.                 currentItem += currC;
  188.                
  189.             }else if (currC == ']') {
  190.                 bracketcount--;
  191.                 currentItem += expr.charAt(i);
  192.                 if (bracketcount == 0) {
  193.                     exprArrL.add(currentItem);
  194.                     currentItem = "";
  195.                 }
  196.                
  197.             }else if ( (currC == '+' || currC == '-' || currC == '/' || currC == '*' || currC == '(' || currC == ')') && bracketcount == 0){
  198.                
  199.                 if (!currentItem.equals("")) {
  200.                     exprArrL.add(currentItem);
  201.                     currentItem = "";
  202.                 }  
  203.                 currentItem += expr.charAt(i);
  204.                 exprArrL.add(currentItem);
  205.                 currentItem = "";
  206.                
  207.             }else if ( (currC == '+' || currC == '-' || currC == '/' || currC == '*' || currC == '(' || currC == ')') && bracketcount > 0){
  208.                 currentItem += expr.charAt(i);
  209.                
  210.             }else if(!(currC == '+' || currC == '-' || currC == '/' || currC == '*' || currC == '(' || currC == ')') ){
  211.                 currentItem += currC;
  212.             }
  213.         }
  214.         if (!currentItem.equals("")) {
  215.             exprArrL.add(currentItem);
  216.             currentItem = "";
  217.         }
  218.        
  219.         //arraylist built change variables into respective values
  220.         for (int i = 0; i < exprArrL.size(); i++) {
  221.             if (exprArrL.get(i).contains("[a-zA-Z]*") && !exprArrL.get(i).contains("[//]//[]*")) {
  222.                 for (int j = 0; j < vars.size() ; j++) {
  223.                     if(vars.get(j).equals(exprArrL.get(i))) {
  224.                         exprArrL.set(i,Integer.toString(vars.get(j).value));
  225.                     }
  226.                 }
  227.             }
  228.         }
  229.            
  230.        
  231.         return exprArrL ;
  232.     }
  233.    
  234.     //push number or value of number into Stack for evaluateSAL//////////////////////////////////////////////////////////////////////////////////////
  235.     private static void pushNum(String currentItem, ArrayList<Variable> vars, Stack<Double> numbers ) {
  236.        
  237.         //variable -push num value
  238.         if (currentItem.matches("^[a-zA-Z]*$")){
  239.             for(int v = 0; v < vars.size() ; v ++) {
  240.                 if (vars.get(v).name.contentEquals( currentItem ) ) {
  241.                     numbers.push((double)vars.get(v).value);
  242.                 }
  243.             }
  244.    
  245.         //is a number - push num value
  246.         }else{
  247.             numbers.push(Double.parseDouble(currentItem));
  248.         }
  249.     }
  250.    
  251.    
  252.     //converts a string with arrname + brackets into a single number//**///////////////////////////////////////////////////////////////////////////////
  253.     private static double convertStrInArray(String exprPiece, ArrayList<Array> arrays, ArrayList<Variable> vars ) {
  254.        
  255.         String firstHalf, middle, secondHalf;
  256.        
  257.         while (exprPiece.contains("]") ) {
  258.            
  259.             String arrName = "";
  260.             int arrNameStartIndex = 0;
  261.             int arrNameEndIndex;
  262.            
  263.             String strInBracket = "";
  264.            
  265.             int startOfStr = 0; ////////// substring of (0,1) (how substring works) - returns whatever is at zero and not at one
  266.             int endOfStr = 0;
  267.                
  268.             //find last [
  269.             for (int s = 0; s < exprPiece.length(); s++) {
  270.                 if (exprPiece.charAt(s) == '[') {
  271.                     startOfStr = s+1;
  272.                 }
  273.             }
  274.             //find first ] after last [
  275.             for (int s = startOfStr; s < exprPiece.length(); s++) {
  276.                 if (exprPiece.charAt(s) == ']') {
  277.                         endOfStr = s;
  278.                         break;
  279.                     }
  280.             }
  281.            
  282.             //brackets are found, find respective name of Array
  283.             arrNameEndIndex = startOfStr-1;             //start of str is first char after bracket //bracket should be one less
  284.             for (int i = startOfStr -2; i > 0 ;i--) {
  285.                 if (Character.isLetter(exprPiece.charAt(i))) {
  286.                     arrNameStartIndex = i;
  287.                 }else {
  288.                     break;
  289.                 }
  290.                
  291.             }
  292.             arrName = exprPiece.substring(arrNameStartIndex,arrNameEndIndex);
  293.            
  294.             //string inside bracket is now found
  295.             strInBracket = exprPiece.substring(startOfStr,endOfStr);
  296.            
  297.             //call create exprArrlist on it and then evaluate the created string array list
  298.             ArrayList<String> ArrLfromStr =  buildArrayListfromString(strInBracket,vars);
  299.             double numResult =  evaluateSAL(ArrLfromStr, arrays, vars);     //this is the number in the bracket
  300.            
  301.             //evaluate number in bracket with convertArray
  302.             numResult = convertArray(arrName,numResult, arrays);
  303.            
  304.            
  305.             //replace evaluated string with number in exprPiece
  306.            
  307.             firstHalf = exprPiece.substring(0,arrNameStartIndex);
  308.             middle = Double.toString(numResult);
  309.             if(!(endOfStr+2 > exprPiece.length()) ) {
  310.                 secondHalf = exprPiece.substring(endOfStr+1,exprPiece.length());
  311.             }else {
  312.                 secondHalf = "";
  313.             }
  314.            
  315.            
  316.             exprPiece = firstHalf + middle + secondHalf;
  317.            
  318.            
  319.         }
  320.         //exprPiece should now be a single number
  321.         return Double.parseDouble(exprPiece);
  322.     }
  323.    
  324.     //private function for convertStrInArray
  325.          private static double convertArray(String inputArrayName, double numInBracket, ArrayList<Array> arrays) {
  326.             // take in something like "b[0]"
  327.              //number in bracket already evaluated to a single number
  328.             double ans = 0;
  329.              
  330.              for (int a = 0; a < arrays.size() ; a ++) {
  331.                 if (arrays.get(a).name.equals(inputArrayName) ){
  332.                             ans = arrays.get(a).values[(int)numInBracket]; 
  333.                 }
  334.             }
  335.         return ans;
  336.     }
  337.    
  338.    
  339.    
  340.    
  341.    
  342.     //input already created ArrayList of Strings ex)||| a + b - (A[0]) ||| and evaluates it returning an int
  343.     // evaluateStringArrayList
  344.     //**////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  345.     private static double evaluateSAL(ArrayList<String> exprArrL, ArrayList<Array> arrays, ArrayList<Variable> vars) {
  346.         Stack<String> operators = new Stack<String>();
  347.         Stack<Double> numbers = new Stack<Double>();
  348.         String currentItem = "";
  349.        
  350.        
  351.        
  352.             for (int x = 0; x < exprArrL.size(); x++) {
  353.                    
  354.                 currentItem = exprArrL.get(x);
  355.                
  356.                
  357.                 if ( currentItem.equals("(") ) {
  358.                 operators.push(currentItem);
  359.                
  360.                 }else if (currentItem.equals(")")) {
  361.                       if (!operators.peek().equals("(") && numbers.size() >= 2 ) {
  362.                          numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
  363.                          operators.pop();
  364.                        }
  365.                        
  366.                       //array needs evaluation before push
  367.                 }else if ( currentItem.contains("[") ){
  368.                     //currentItem = Integer.toString(convertArray(currentItem, arrays, vars)) ;
  369.                     pushNum(currentItem,vars,numbers);
  370.                    
  371.                     // push operator into ops stack
  372.                 }else if (currentItem.equals( "+") || currentItem.equals( "-" )|| currentItem.equals( "*" )|| currentItem.equals( "/")) {
  373.                        // While top of 'ops' has same or greater precedence to current
  374.                        // token, which is an operator. Apply operator on top of 'ops'
  375.                        // to top two elements in values stack
  376.                        while (!operators.isEmpty() && hasPrecedence(currentItem, operators.peek()))
  377.                            numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
  378.          
  379.                        // Push current token to 'ops'.
  380.                        operators.push(currentItem);
  381.                
  382.                        //variable or num, can be pushed in
  383.                 }else {
  384.                     pushNum(currentItem,vars,numbers);
  385.                    
  386.                 }
  387.                
  388.             }
  389.             while (!operators.isEmpty()) {
  390.                 if( operators.peek().equals("(")) {
  391.                     operators.pop();
  392.                 }else {
  393.                     numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
  394.                 }
  395.             }
  396.      
  397.             // Top of 'values' contains result, return it
  398.             return numbers.pop();
  399.     }
  400.    
  401.     // Apply operation used in evaluateSAL ////////////////////////////////////////////////////////////
  402.     private static double applyOperation(String op, double  b, double a) {
  403.        
  404.         switch (op)
  405.         {
  406.         case "+":
  407.             return a + b;
  408.         case "-":
  409.             return a - b;
  410.         case "*":
  411.             return a * b;
  412.         case "/":
  413.             if (b == 0)
  414.                 throw new
  415.                 UnsupportedOperationException("Cannot divide by zero");
  416.             return a / b;
  417.         }
  418.         return 0;
  419.     }
  420.    
  421.     // Precedence checker used in evaluateSAL ///////////////////////////////////////////////////////////
  422.     private static boolean hasPrecedence(String op1, String op2) {
  423.         if (op2.equals("(") || op2.equals( ")")) {
  424.                return false;
  425.         }
  426.         if ((op1.equals( "*") || op1.equals( "/")) && (op2.equals( "+" )|| op2.equals( "-")) ) {
  427.              return false;
  428.         }else {
  429.              return true;
  430.         }
  431.            
  432.     }
  433. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement