📄 expression.java
字号:
/*
* @(#)Expression.java Version 1.0 98/03/12
*
* Copyright (c) 1998 by Huahai Yang
*
* Use at your own risk. I do not guarantee the fitness of this
* software for any purpose, and I do not accept responsibility for
* any damage you do to yourself or others by using this software.
* This file may be distributed freely, provided its contents
* are not tampered with in any way.
*
*/
import java.util.*;
/**
* Expression implements an simple arithmetic expression
* ( can only handle 6 operators: +, -, *, /, ( and ) )
* evaluation algorithem called operator precedence parsing.
* Treats a String or a Vector as expression and return its
* value (double) or throw an exception. It can skip whitespace.
*
* @version 1.0, 03/12/98
* @author Huahai Yang
*/
public class Expression
{
protected String inputExpression;
private Stack operatorStack, //operator stack for conversion
postFixStack; //stack for postfix machine
//define tokens
private final int EOL = 0, //end of line
VALUE = 1, //number
OPAREN = 2, //open parenthesis
CPAREN = 3, //close parenthesis
MULT = 4, //multiply
DIV = 5, //division
PLUS = 6,
MINUS = 7;
//define token precedences
private final int [] INPUT_PRECEDENCE =
{ 0, 0, 100, 0, 3, 3, 1, 1 },
STACK_PRECEDENCE =
{ -1, 0, 0, 99, 4, 4, 2, 2 };
private double currentValue;
private double theResult;
private int lastToken;
/**
* Constructs an empty exprssion
*/
public Expression()
{
inputExpression = null;
operatorStack = new Stack();
postFixStack = new Stack();
operatorStack.push(new Integer(EOL));
} // 0 param constructor
/**
* Takes a String as an expression
* @param inString input string
*/
public Expression(String inString)
{
inputExpression = inString.trim();
operatorStack = new Stack();
postFixStack = new Stack();
operatorStack.push(new Integer(EOL));
} // string param constructor
/**
* Takes a vector as an expression, by converting elements of
* vector into strings
* @param inVector input vector
*/
public Expression(Vector inVector)
{
StringBuffer tmpString = new StringBuffer();
for (Enumeration e = inVector.elements(); e.hasMoreElements();)
{
tmpString.append( e.nextElement() ) ;
} // for
inputExpression = (tmpString.toString()).trim();
operatorStack = new Stack();
postFixStack = new Stack();
operatorStack.push(new Integer(EOL));
} // vector param constructor
/**
* Sets the input string
* @param inString input string
*/
public void setExpression(String inString)
{
inputExpression = inString;
} // setExpression
/**
* Gets the result of expression
* @return result value of this expression
* @exception IllegalExpressionException if encounter error while
* while parsing input string as an expression
*/
public double getValue() throws IllegalExpressionException
{
String token;
char firstChar;
StringTokenizer parser =
new StringTokenizer(inputExpression, "+-*/() ", true);
do
{
//end of expression
if(!parser.hasMoreTokens())
{
lastToken = EOL;
processToken();
continue;
} // if
token = parser.nextToken();
firstChar = token.charAt(0);
// skip the ' '
if(Character.isWhitespace(firstChar))
{
continue;
} // if
if( (token.length() == 1) && isOperator(firstChar) )
{
switch (firstChar)
{
case '+':
lastToken = PLUS;
break;
case '-':
lastToken = MINUS;
break;
case '*':
lastToken = MULT;
break;
case '/':
lastToken = DIV;
break;
case '(':
lastToken = OPAREN;
break;
case ')':
lastToken = CPAREN;
break;
} // switch
} // if is operator
else
{
try
{
currentValue = Double.valueOf(token).doubleValue();
lastToken = VALUE;
} //try
catch ( NumberFormatException e )
{
throw new IllegalExpressionException("Unknown symbol");
} //catch
} // else suppose a number
processToken();
} while( lastToken != EOL );
if( postFixStack.empty() )
{
throw new IllegalExpressionException("Missing operand");
} // if missing operand
theResult = ((Double)postFixStack.pop()).doubleValue();
if( !postFixStack.empty() )
{
throw new IllegalExpressionException("Missing operator");
} // if missing operator
return theResult;
} // getValue
private void processToken() throws IllegalExpressionException
{
int topOperator;
switch(lastToken)
{
case VALUE:
postFixStack.push(new Double(currentValue));
return;
case CPAREN:
while( (topOperator =
((Integer)operatorStack.peek()).intValue())
!= OPAREN && topOperator != EOL )
{
applyOperation( topOperator );
} // while
if( topOperator == OPAREN )
{
operatorStack.pop();
} // if
else
{
throw new IllegalExpressionException("Missing " +
"open parenthesis");
} //else
break;
default:
while( INPUT_PRECEDENCE[lastToken] <=
STACK_PRECEDENCE[ topOperator =
((Integer)operatorStack.peek()).intValue() ] )
{
applyOperation( topOperator );
} //while
if( lastToken != EOL )
{
operatorStack.push(new Integer(lastToken));
} // if
break;
} //switch
} //processToken
private void applyOperation(int topOperator)
throws IllegalExpressionException
{
double leftOperand,
rightOperand;
if( topOperator == OPAREN )
{
throw new IllegalExpressionException("Unbalanced parenthesis");
} //if
rightOperand = getPostStackTop();
leftOperand = getPostStackTop();
if( topOperator == PLUS )
{
postFixStack.push(new Double(leftOperand + rightOperand));
} // if +
else if( topOperator == MINUS )
{
postFixStack.push(new Double(leftOperand - rightOperand));
} // else if -
else if( topOperator == MULT )
{
postFixStack.push(new Double(leftOperand * rightOperand));
} // else if *
else if( topOperator == DIV )
{
if( rightOperand != 0)
{
postFixStack.push(new Double(leftOperand / rightOperand));
} // if
else
{
throw new IllegalExpressionException("Division by zero");
} // else erro
} // if /
operatorStack.pop();
} // applyOperation
private double getPostStackTop() throws IllegalExpressionException
{
if( postFixStack.empty() )
{
throw new IllegalExpressionException("Missing operand");
} // if
return ((Double)postFixStack.pop()).doubleValue();
} //getPostStackTop
private boolean isOperator(char c)
{
return (c == '+' || c =='-' || c == '*' || c == '/'
|| c == '(' || c == ')' );
} // isOperator
} // Expression
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -