You are to write a program name calc.java that evaluates an infix expression ent
ID: 3855894 • Letter: Y
Question
You are to write a program name calc.java that evaluates an infix expression entered by the user. The expression may contain the following tokens: (1) Integer constants (a series of decimal digits). (2) x (representing a value to be supplied later) (4) Binary operators (+, -, *, /and %). (5) Parentheses Spaces between tokens are allowed but not required. The program will convert the expression to postfix (RPN) form and display the converted expression. The following example illustrates the behavior of the program (user input is in bold and red) Program output is in bold and green. Enter infix expression: (7 + 1)*(8 - 2)/4 Converted expression: 71 + 82 - *4/ The result is: 12 Now, solve the postfix expression and return a result. You must now use an operand stack to process the postfix expression. Display this result on the screen as well as the postfix expression as shown above. If the infix expression contains an error of any kind, the program must display the message Error in expression (with an optional explanation) and then terminate. The following examples illustrate various types of errors: Enter infix expression: 12+ Error in expression!! No operator between operands. Also last token must be an operand. Enter infix expression: 10.4 Error in expression!! Cannot accept floating point numbers. Enter infix expression: 1(+2) Error in expression!! No operator between operand and left parentheses. Enter infix expression: 5 - (x - 2) Error in expression!! No matching left parentheses for a right parentheses Enter infix expression: 1**2 Error in expression!! The * operator cannot be preceded by a * operator. The output of your program must match the format illustrated in this example. Here are some other additional requirements for this program: (1) You must use stack objects during the translation from infix to postfix. (2) Operators must have the correct precedence and associativity. Binary operators *, /and % takes precedence over binary + and -. And processing is always done from left to right.Explanation / Answer
import java.util.Stack;
public class Calc
{
public static int evaluate(String expression)
{
char[] tokens = expression.toCharArray();
// Stack for numbers: 'values'
Stack<Integer> values = new Stack<Integer>();
// Stack for Operators: 'ops'
Stack<Character> ops = new Stack<Character>();
for (int i = 0; i < tokens.length; i++)
{
// Current token is a whitespace, skip it
if (tokens[i] == ' ')
continue;
// Current token is a number, push it to stack for numbers
if (tokens[i] >= '0' && tokens[i] <= '9')
{
StringBuffer sbuf = new StringBuffer();
// There may be more than one digits in number
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
}
// Current token is an opening brace, push it to 'ops'
else if (tokens[i] == '(')
ops.push(tokens[i]);
// Closing brace encountered, solve entire brace
else if (tokens[i] == ')')
{
while (ops.peek() != '(')
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.pop();
}
// Current token is an operator.
else if (tokens[i] == '+' || tokens[i] == '-' ||
tokens[i] == '*' || tokens[i] == '/')
{
// While top of 'ops' has same or greater precedence to current
// token, which is an operator. Apply operator on top of 'ops'
// to top two elements in values stack
while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this point, apply remaining
// ops to remaining values
while (!ops.empty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Top of 'values' contains result, return it
return values.pop();
}
// Returns true if 'op2' has higher or same precedence as 'op1',
// otherwise returns false.
public static boolean hasPrecedence(char op1, char op2)
{
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
// A utility method to apply an operator 'op' on operands 'a'
// and 'b'. Return the result.
public static int applyOp(char op, int b, int a)
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new
UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
// Driver method to test above methods
public static void main(String[] args)
{
System.out.println(Calc.evaluate("10 + 2 * 6"));
System.out.println(Calc.evaluate("100 * 2 + 12"));
System.out.println(Calc.evaluate("100 * ( 2 + 12 )"));
System.out.println(Calc.evaluate("100 * ( 2 + 12 ) / 14"));
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.