Question
JAVA CODE NEEDED! B) The evaluator() method also has to be adjusted to scan from left to right. There are several changes: i) When a
JAVA CODE NEEDED!
B) The evaluator() method also has to be adjusted to scan from left to right.
There are several changes:
i) When a left parenthesis is encountered it is always pushed onto stack A
unless it signals a negative number (as in 5+ (-13.4) +2). In that case, formNum() should
be called to compute the negative number and push it as a double onto B,
and the corresponding right parenthesis should be skipped over.
ii) When a right parenthesis is encountered (but not the right end of a negative number),
it triggers a call to evalDown() to evaluate the operations in a parenthesized
subexpression until the corresponding left parenthesis is reached.
The left parenthesis is also popped from A.
iii) when the current token operator is equal in precedence to the
operator at the top of the stack, do not push the token. Instead,
perform the operation at the top of the A stack using eval(), and then compare
the current token operator to the new top of the A stack.
Example. Suppose we have 3.0 / 2.0 * 4.0 .
We push 3 onto B , / onto A, and 2 onto B.
If we (incorrectly) push * onto A (it has equal precedence with /),
and then 4 onto B, we will compute 2 * 4 first and then 3/8..
Instead, we should compute 3./2 first and push 1.5, and later
compute 1.5 * 4 = 6.0. (In right to left scanning, we always
pushed the new operator if it had equal precedence with the top operator,
now we do not push it.)
iv) push a new token operator or left parenthesis (except one indicating a
negative number) on top of a left parenthesis at the top of stack A.
MY CODE: import java.util.Scanner; /* arithmetic expression evaluator; evaluate an arithmetic expression represented as a string withou blanks and negative numbers indicated by underscore.*/ public class ExprEval { /*expressions are evaluated from right to left, using a stack A of arithmetic operators and a stack B of operands. In this method, a subexpression is evaluated by popping the current operator from A, its 2 operands from B, performing the operation and pushing the result onto B, and then repeating until a right parenthesis is encountered or there are no more operators */ public static void evalDown(Stack1gen A, Stack1gen B) { do { char op = A.pop(); double opnd1 = B.pop(); double opnd2 = B.pop(); double val = 0.0; switch (op) { case '+': val = opnd1 + opnd2; break; case '-': val = opnd1 - opnd2; break; case '*': val = opnd1 * opnd2; break; case '/': val = opnd1/opnd2; break; } B.push(val); }while((A.getSize()>0) && (A.getTop() != ')')); if((A.getSize()>0) && (A.getTop() == ')')) { A.pop(); } }
//evaluate the current operation at top of A and push the result onto B public static void eval(Stack1gen A, Stack1gen B) { char op = A.pop(); //current operator double opnd1 = B.pop(); //operands double opnd2 = B.pop(); double val = 0.0; switch (op) //evaluate { case '+': val = opnd1 + opnd2; break; case '-': val = opnd1 - opnd2; break; case '*': val = opnd1 * opnd2; break; case '/': val = opnd1/opnd2; break; } B.push(val); //push result onto B }
//compare the current operator token in the input string to the operator //on top of stack A to determine precedence. public static boolean prec(char token, Stack1gen A) { char topOp = A.getTop(); if((token == '*') || (token == '/')) { return true; //token has precedence, so it will be pushed onto A } else { if((topOp == '*') || (topOp == '/')) { return false; //operator at top of A has precedence } else { return true; //token is ')', which is always pushed } } }
//the program inputs a single expression string via keyboard, //evaluates it, and displays the result. public static void main(String[] args) { Scanner kb = new Scanner(System.in);
Stack1gen stackB = new Stack1gen(); //operands Stack1gen stackA = new Stack1gen(); //operators
Expr exp = new Expr(); String ee = exp.getExpr(); //the input expression (as a String) int pp; //pointer to current token in input string char token; //current token //loop to scan the string right to left do { pp = exp.getp(); token = ee.charAt(pp); if(token == ')') { stackA.push(token); //always push a right parenthesis to delimit a subexpression pp--; exp.setp(pp); }
//if the token is a left parenthesis, //evaluate the corresponding subexpression if(token == '(') { evalDown(stackA, stackB); pp--; exp.setp(pp); }
if((token=='+')||(token=='-')||(token=='*')||(token=='/')) { //If the token is an arithmetic operator of higher precedence //than the topmost operator on stack A, push the token onto A. if((stackA.getSize() == 0) || (prec(token, stackA) == true)) { stackA.push(token); pp--; exp.setp(pp); } //If the token is an arithmetic operator of lower precedence than that //at the top of the stack, then evaluate the operation at the top of stack A. else { eval(stackA, stackB); } } //if the token is the rightmost digit of a number or a decimal point on the right, //form the number as a double and push onto stack B if(((token<='9')&&(token>='0'))||(token=='.')) { stackB.push(exp.formNum()); } }while(exp.getp()>=0);//continue to scan from right to left
//after completely scanning the input string, evaluate any remaining op[erations while(stackA.getSize()>0) { eval(stackA,stackB); }
System.out.println(stackB.pop()); } //end of main }
Expr.java
import java.util.Scanner;
//class for evaluating arithmetic expressions public class Expr { Scanner kb = new Scanner(System.in);
//variables for an Expr object private String e; private int p; //pointer to characters within the expression string e private int len;
//constructor public Expr() { System.out.println("Enter an expression"); e = kb.nextLine(); //input a string as a line of keyboard input. len = e.length(); p = len-1; //position pointer at right end of the expression }
//print the current character and advance the pointer (to the left) public void printChar() { System.out.println(e.charAt(p)); p = p-1; }
public String getExpr() { return e; }
public int getp() { return p; }
public void setp(int pp) { p = pp; }
//if string e represents a number (possibly with a decimal point, possibly negative), //return the numerical value of the string as a double value public double formNum() { double total = 0.0; int count = 0; int flag = 0; double mult = 1.0; char c,d; do { c = e.charAt(p); //examine the current character in the string (from right to left) if(c == '.') { flag = 1; //set a flag to remember that the character is a decimal point } else { //if the current character is a digit, convert to its //int value and include it in the value corresponding to the string. if((c >= '0') && (c<= '9')) { total = total + mult*(c-'0'); mult = mult*10.0; if(flag==0) { count++; //count the number of digits to the right of a possible decimal point } } else { if(c == '_') { total = -total; //an underscore character represents a negative value } } } p--; //prepare to move to the next character to the left d = '?'; if(p>= 0) { d = e.charAt(p); //the next character to the left } }while((p>=0) && (((d<='9')&&(d>='0'))||(d=='_')||(d=='.')));//check for a valid character if(flag==1) { total = total/Math.pow(10.0,count*1.0); //compute the value taking into account //the number of decimal places } return total; } }
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started