Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package apps;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.NoSuchElementException;
- import java.util.Scanner;
- import java.util.StringTokenizer;
- import structures.Stack;
- public class Expression {
- /**
- * Expression to be evaluated
- */
- String expr;
- /**
- * Scalar symbols in the expression
- */
- ArrayList<ScalarSymbol> scalars;
- /**
- * Array symbols in the expression
- */
- ArrayList<ArraySymbol> arrays;
- /**
- * Positions of opening brackets
- */
- ArrayList<Integer> openingBracketIndex;
- /**
- * Positions of closing brackets
- */
- ArrayList<Integer> closingBracketIndex;
- /**
- * String containing all delimiters (characters other than variables and constants),
- * to be used with StringTokenizer
- */
- public static final String delims = " \t*+-/()[]";
- /**
- * Initializes this Expression object with an input expression. Sets all other
- * fields to null.
- *
- * @param expr Expression
- */
- public Expression(String expr) {
- this.expr = expr;
- scalars = null;
- arrays = null;
- openingBracketIndex = null;
- closingBracketIndex = null;
- }
- /**
- * Matches parentheses and square brackets. Populates the openingBracketIndex and
- * closingBracketIndex array lists in such a way that closingBracketIndex[i] is
- * the position of the bracket in the expression that closes an opening bracket
- * at position openingBracketIndex[i]. For example, if the expression is:
- * <pre>
- * (a+(b-c))*(d+A[4])
- * </pre>
- * then the method would return true, and the array lists would be set to:
- * <pre>
- * openingBracketIndex: [0 3 10 14]
- * closingBracketIndex: [8 7 17 16]
- * </pre>
- *
- * See the FAQ in project description for more details.
- *
- * @return True if brackets are matched correctly, false if not
- */
- public boolean isLegallyMatched() { // TODO: IDK if this is working 100% properly
- openingBracketIndex = new ArrayList<Integer>();
- closingBracketIndex = new ArrayList<Integer>();
- matchParens(this.expr, 0);
- return openingBracketIndex.size() == closingBracketIndex.size();
- }
- private void matchParens(String expr, int orig) {
- for(int i = 0; i < expr.length(); i++) {
- if(expr.charAt(i) == '(') {
- while(expr.charAt(i) != ')') {
- }
- }
- }
- }
- /**
- * Populates the scalars and arrays lists with symbols for scalar and array
- * variables in the expression. For every variable, a SINGLE symbol is created and stored,
- * even if it appears more than once in the expression.
- * At this time, the constructors for ScalarSymbol and ArraySymbol
- * will initialize values to zero and null, respectively.
- * The actual values will be loaded from a file in the loadSymbolValues method.
- */
- public void buildSymbols() {
- scalars = new ArrayList<ScalarSymbol>();
- arrays = new ArrayList<ArraySymbol>();
- for (int i = 0; i < expr.length(); i++){
- if (Character.isLetter(expr.charAt(i))) {
- String currentSymbol = "";
- boolean isArray = false;
- while (i < expr.length() && Character.isLetter(expr.charAt(i))){
- currentSymbol += expr.charAt(i);
- i++;
- }
- if (i<expr.length() && expr.charAt(i) == '[') {
- arrays.add(new ArraySymbol(currentSymbol));
- } else {
- scalars.add(new ScalarSymbol(currentSymbol));
- }
- }
- }
- }
- /**
- * Loads values for symbols in the expression
- *
- * @param sc Scanner for values input
- * @throws IOException If there is a problem with the input
- */
- public void loadSymbolValues(Scanner sc)
- throws IOException {
- while (sc.hasNextLine()) {
- StringTokenizer st = new StringTokenizer(sc.nextLine().trim());
- int numTokens = st.countTokens();
- String sym = st.nextToken();
- ScalarSymbol ssymbol = new ScalarSymbol(sym);
- ArraySymbol asymbol = new ArraySymbol(sym);
- int ssi = scalars.indexOf(ssymbol);
- int asi = arrays.indexOf(asymbol);
- if (ssi == -1 && asi == -1) {
- continue;
- }
- int num = Integer.parseInt(st.nextToken());
- if (numTokens == 2) { // scalar symbol
- scalars.get(ssi).value = num;
- } else { // array symbol
- asymbol = arrays.get(asi);
- asymbol.values = new int[num];
- // following are (index,val) pairs
- while (st.hasMoreTokens()) {
- String tok = st.nextToken();
- StringTokenizer stt = new StringTokenizer(tok," (,)");
- int index = Integer.parseInt(stt.nextToken());
- int val = Integer.parseInt(stt.nextToken());
- asymbol.values[index] = val;
- }
- }
- }
- }
- /**
- * Evaluates the expression, using RECURSION to evaluate subexpressions and to evaluate array
- * subscript expressions. (Note: you can use one or more private helper methods
- * to implement the recursion.)
- *
- * @return Result of evaluation
- */
- public float evaluate() {
- // COMPLETE THIS METHOD
- printScalars();
- printArrays();
- String expression = expr;
- float ans = evaluate(expression);
- try {
- return ans;
- } catch (Exception e){
- return 0;
- }
- }
- private float evaluate(String expr) {
- StringTokenizer tokens= new StringTokenizer(expr, delims);
- Stack<String> expressions = new Stack<String>();
- while(tokens.hasMoreTokens()){
- System.out.println(tokens.nextToken());
- }
- return 0.0f;
- }
- // private float evaluate(String expr) { // private method made for recursive purposes
- // if(expr.length() == 1 && Character.isDigit(expr.charAt(0))) {
- // return (float) Character.getNumericValue(expr.charAt(0));
- // }
- //
- // Stack<Float> numStack = new Stack<Float>(); // num stack
- // Stack<Character> opStack = new Stack<Character>(); // char stack
- //
- // for (int i=0; i<expr.length();i++) {
- // if (expr.charAt(i) == '(') {
- // System.out.println("Before expr: " + expr);
- // int removed = openingBracketIndex.remove(0);
- // int openIdx = i;
- // int closeIdx = closingBracketIndex.remove(0);
- // int distance = closeIdx-removed;
- // int replacement = (int) evaluate(expr.substring(openIdx + 1, distance));
- // System.out.println(replacement);
- // expr = expr.substring(0, openIdx) + replacement + expr.substring(distance+1);
- // System.out.println("After expr: " + expr);
- // }
- //
- // if (Character.isDigit(expr.charAt(i))) {
- // String num = "";
- // int len = expr.length();
- // while((i < len) && (Character.isDigit(expr.charAt(i)))){
- // num += expr.charAt(i);
- // i++;
- // }
- //
- // numStack.push((float) Integer.parseInt(num));
- //
- // if(i == expr.length()) {
- // break;
- // }
- // }
- //
- // if (isOperand(expr.charAt(i))) {
- // opStack.push(expr.charAt(i));
- // }
- //
- // if (variableIndex(expr.charAt(i)) != -1 ) {
- // int num = variableIndex(expr.charAt(i));
- // numStack.push((float) scalars.get(num).value);
- // }
- // }
- //
- //
- // while(!(opStack.isEmpty())) {
- // float first = numStack.pop();
- // float second = numStack.pop();
- // switch(opStack.pop()) {
- // case '+':
- // // add
- // int addResult = (int) (second + first);
- // numStack.push((float) addResult);
- // break;
- // case '-':
- // // subtract
- // int subtractResult = (int) (second - first);
- // numStack.push((float) subtractResult);
- // break;
- // case '*':
- // // multiply
- // int multiplyResult = (int) (second * first);
- // numStack.push((float) multiplyResult);
- // break;
- // case '/':
- // // divide
- // int divideResult = (int) (second / first);
- // numStack.push((float) divideResult);
- // break;
- // default:
- // // do nothing
- // break;
- // };
- // }
- //
- // return numStack.pop();
- //
- // }
- //
- private int variableIndex(char ch) {
- for (int i=0;i<scalars.size();i++) {
- if (Character.toString(ch).equals(scalars.get(i).name)) {
- return i;
- }
- }
- return -1;
- }
- private boolean isOperand(char ch) {
- return ch == '+' || ch == '-' || ch == '*' || ch == '/';
- }
- /**
- * Utility method, prints the symbols in the scalars list
- */
- public void printScalars() {
- for (ScalarSymbol ss: scalars) {
- System.out.println(ss);
- }
- }
- /**
- * Utility method, prints the symbols in the arrays list
- */
- public void printArrays() {
- for (ArraySymbol as: arrays) {
- System.out.println(as);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement