mirror of
https://github.com/Rushilwiz/APCS.git
synced 2025-04-04 20:40:20 -04:00
244 lines
5.7 KiB
Java
244 lines
5.7 KiB
Java
// Name: B6-24
|
|
// Date: 10/7/19
|
|
import java.util.*;
|
|
|
|
/**
|
|
* This program calculates the value of an expression
|
|
* consisting of numbers, arithmetic operators, and parentheses.
|
|
*/
|
|
public class ExpressionEvaluator
|
|
{
|
|
public static void main(String[] args)
|
|
{
|
|
Scanner in = new Scanner(System.in);
|
|
System.out.print("Enter an expression: ");
|
|
// 3+4*5 23
|
|
// (3+4)*5 35
|
|
// (4+5)-5*3 -6
|
|
// (3+4)*(5+6) 77
|
|
// (3*(4+5)-2)/5 5
|
|
// 2*3*4-9/3 21
|
|
/* extension, left-to-right processing */
|
|
// 6*8/6 6
|
|
// 2-3+5 -6
|
|
// 3*4/6 0
|
|
// 3+4-5+2*2 6
|
|
|
|
String input = in.nextLine().trim();
|
|
Evaluator e = new Evaluator(input);
|
|
int value = e.getExpressionValue();
|
|
//int value = e.getExpressionValueEXT(); //extension
|
|
System.out.println(input + " = " + value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A class that can compute the value of an arithmetic expression.
|
|
*/
|
|
class Evaluator
|
|
{
|
|
private ExpressionTokenizer tokenizer;
|
|
|
|
/**
|
|
* Constructs an evaluator.
|
|
* @param anExpression a string containing the expression
|
|
* to be evaluated
|
|
*/
|
|
public Evaluator(String anExpression)
|
|
{
|
|
tokenizer = new ExpressionTokenizer(anExpression);
|
|
}
|
|
|
|
/**
|
|
* Evaluates the expression.
|
|
* @return the value of the expression.
|
|
*/
|
|
public int getExpressionValue()
|
|
{
|
|
int value = getTermValue();
|
|
String next = tokenizer.peekToken();
|
|
if("+".equals(next)) {
|
|
tokenizer.nextToken();
|
|
value += getExpressionValue();
|
|
} else if("-".equals(next)) {
|
|
tokenizer.nextToken();
|
|
value -= getExpressionValue();
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Evaluates the next term found in the expression.
|
|
* @return the value of the term
|
|
*/
|
|
public int getTermValue()
|
|
{
|
|
int value = getFactorValue();
|
|
String next = tokenizer.peekToken();
|
|
if("*".equals(next)) {
|
|
tokenizer.nextToken();
|
|
value *= getTermValue();
|
|
} else if("/".equals(next)) {
|
|
tokenizer.nextToken();
|
|
value /= getTermValue();
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Evaluates the next factor found in the expression.
|
|
* @return the value of the factor
|
|
*/
|
|
public int getFactorValue()
|
|
{
|
|
int value;
|
|
String next = tokenizer.peekToken();
|
|
if ("(".equals(next))
|
|
{
|
|
tokenizer.nextToken(); // Discard "("
|
|
value = getExpressionValue();
|
|
tokenizer.nextToken(); // Discard ")"
|
|
}
|
|
else
|
|
{
|
|
if(!next.equals("-")) {
|
|
value = Integer.parseInt(tokenizer.nextToken());
|
|
} else {
|
|
tokenizer.nextToken();
|
|
value = -1 * Integer.parseInt(tokenizer.nextToken());
|
|
}
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Extension
|
|
*
|
|
*/
|
|
public int getExpressionValueEXT()
|
|
{
|
|
int value = getTermValueEXT();
|
|
String next = tokenizer.peekToken();
|
|
if("+".equals(next)) {
|
|
tokenizer.nextToken();
|
|
return value += getTermValueEXT();
|
|
} else if("-".equals(next)) {
|
|
tokenizer.nextToken();
|
|
return value -= getTermValueEXT();
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Extension
|
|
*
|
|
*/
|
|
public int getTermValueEXT()
|
|
{
|
|
int value = getFactorValueEXT();
|
|
String next = tokenizer.peekToken();
|
|
if("*".equals(next)) {
|
|
tokenizer.nextToken();
|
|
return value *= getFactorValueEXT();
|
|
} else if("/".equals(next)) {
|
|
tokenizer.nextToken();
|
|
return value /= getFactorValueEXT();
|
|
}
|
|
return value;
|
|
|
|
}
|
|
|
|
/**
|
|
* Extension
|
|
*
|
|
*/
|
|
public int getFactorValueEXT()
|
|
{
|
|
int value;
|
|
String next = tokenizer.peekToken();
|
|
if ("(".equals(next))
|
|
{
|
|
tokenizer.nextToken(); // Discard "("
|
|
value = getExpressionValueEXT();
|
|
tokenizer.nextToken(); // Discard ")"
|
|
}
|
|
else
|
|
{
|
|
if(!next.equals("-")) {
|
|
value = Integer.parseInt(tokenizer.nextToken());
|
|
} else {
|
|
tokenizer.nextToken();
|
|
value = -1 * Integer.parseInt(tokenizer.nextToken());
|
|
}
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This class breaks up a string describing an expression
|
|
* into tokens: numbers, parentheses, and operators.
|
|
*/
|
|
class ExpressionTokenizer
|
|
{
|
|
private String input;
|
|
private int start; // The start of the current token
|
|
private int end; // The position after the end of the current token
|
|
|
|
/**
|
|
* Constructs a tokenizer.
|
|
* @param anInput the string to tokenize
|
|
*/
|
|
public ExpressionTokenizer(String anInput)
|
|
{
|
|
input = anInput;
|
|
start = 0;
|
|
end = 0;
|
|
nextToken(); // Find the first token
|
|
}
|
|
|
|
/**
|
|
* Peeks at the next token without consuming it.
|
|
* @return the next token or null if there are no more tokens
|
|
*/
|
|
public String peekToken()
|
|
{
|
|
if (start >= input.length()) {
|
|
return null; }
|
|
else {
|
|
return input.substring(start, end); }
|
|
}
|
|
|
|
/**
|
|
* Gets the next token and moves the tokenizer to the following token.
|
|
* @return the next token or null if there are no more tokens
|
|
*/
|
|
public String nextToken()
|
|
{
|
|
String r = peekToken();
|
|
start = end;
|
|
if (start >= input.length()) {
|
|
return r;
|
|
}
|
|
if (Character.isDigit(input.charAt(start)))
|
|
{
|
|
end = start + 1;
|
|
while (end < input.length()
|
|
&& Character.isDigit(input.charAt(end)))
|
|
{
|
|
end++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
end = start + 1;
|
|
}
|
|
return r;
|
|
}
|
|
} |