import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/*A class ListExpression: generate the instance with a string*/
class ListExpression {
private Vector expression; //member variable
private String string;
public ListExpression() {} //default construct
/*constructor with a string as a parameter*/
public ListExpression(String str) {
this.expression = rightConstruct(getExpr(str));
this.string=getExpr(str);
}
public Vector getExpression(){
return expression;
}
public void setExpression(Vector expression){
this.expression=expression;
}
/*
*decide which methods to use according that whether there are brackets with each operator
*para: string
*return: vector
*/
Vector rightConstruct(String str){
StringTokenizer spaceToken = new StringTokenizer(str);
int len1=spaceToken.countTokens();
String[] strArr=new String[len1];
String subStr="";
for (int i = 0; i <len1 ; i++){
strArr[i]= spaceToken.nextToken();
subStr+=strArr[i];
}
Vector right=construct(subStr);
int i=1;
while (i<len1)
{
if (strArr[i].equals("+") || strArr[i].equals("-") || strArr[i].equals("*") || strArr[i].equals("/"))
{
if(!(strArr[i-1].endsWith(")") || strArr[i+1].startsWith("(")))
{
String cStr="";
i++;
while (!(strArr[i].equals("+") || strArr[i].equals("-") || strArr[i].equals("*") || strArr[i].equals("/")))
{
cStr+=strArr[i];
if(i<len1-1)
i++;
else break;
}
if (!cStr.contains(")"))
{
right=bracketConstruct(str);
break;
}
}
}
i++;
}
return right;
}
/*
*change a string to a string with brackets with each operator and call the construct function
*para: string
*return: vector
*/
Vector bracketConstruct(String str){
StringTokenizer spaceToken = new StringTokenizer(str);
String noSpaceStr ="";
int len1=spaceToken.countTokens();
String[] strArr=new String[len1];
for (int i = 0; i <len1 ; i++) {
strArr[i]= spaceToken.nextToken();
noSpaceStr+=strArr[i];
}
int i=0;
while (i<strArr.length-3)
{
if (noSpaceStr.charAt(i)=='+' || noSpaceStr.charAt(i)=='-' || noSpaceStr.charAt(i)=='/' || noSpaceStr.charAt(i)=='*')
{
if (noSpaceStr.charAt(i+2)!=')' && Character.isDigit(noSpaceStr.charAt(i+1)))
{
for (int k=i+1;k<noSpaceStr.length() ;k++ )
{
if (noSpaceStr.charAt(k)=='+' || noSpaceStr.charAt(k)=='-' || noSpaceStr.charAt(i)=='*' || noSpaceStr.charAt(i)=='/')
{
noSpaceStr=noSpaceStr.substring(0,k)+")"+noSpaceStr.substring(k);
break;
}
}
for (int j=i-2;j>=0 ;j-- )
{
if (noSpaceStr.charAt(j)=='(')
{
noSpaceStr=noSpaceStr.substring(0,j)+"("+noSpaceStr.substring(j);
break;
}
}
}
}
i++;
}
return construct(noSpaceStr);
}
/*
*delete the first brackets and call the function constructVector() to return the required vector
*para: string
*return: vector
*/
Vector construct(String noSpaceStr){
String subStr="";
if ((noSpaceStr.charAt(0)=='(')&&(noSpaceStr.charAt(noSpaceStr.length()-1)==')'))
{
subStr=noSpaceStr.substring(1,noSpaceStr.length());
}
return constructVector(subStr);
}
/*
*with a string as the parameter, construct the Polish Notation using vectors
*para: string
*return: vector
*/
Vector constructVector(String noSpaceStr) {
Vector expr = new Vector();
StringTokenizer strToken = new StringTokenizer(noSpaceStr, "(+*-/)",true);
String[] strArr = new String[strToken.countTokens()];
int len=strToken.countTokens();
for (int i = 0; i <len ; i++)
strArr[i] = strToken.nextToken();
int i = 0;
int left=0;
int right=0;
while (i < strArr.length) {
/*if meet with a "(", add every string until the right ")", we use two variables left and right to control the number of brackets
then make a recursive call with the new substring as a parameter*/
if (strArr[i].equals("("))
{
left++;
i++;
String subStr="";
while (true)
{
if (strArr[i].equals("("))
{
left++;
}
if (strArr[i].equals(")"))
{
right++;
}
if (right!=left)
{
subStr+=strArr[i];
i++;
}
else break;
}
expr.add(constructVector(subStr));
}
/*if meet with operators, add them to the first position of the vector, else just add them to the vector*/
if (strArr[i].equals("+") || strArr[i].equals("*") || strArr[i].equals("-")|| strArr[i].equals("/")) {
expr.add(0, strArr[i]);
i++;
}
else if (strArr[i].startsWith("sin") || strArr[i].startsWith("cos") || strArr[i].startsWith("tan")|| strArr[i].startsWith("cot")) {
expr.add(0,strArr[i].substring(0,3));
if(strArr[i].length()>3)
expr.add(strArr[i].substring(3));
i++;
}
else if(strArr[i].equals(")")){
i++;
}
else{
expr.add(strArr[i]);
i++;
}
}
return expr;
}
/*
*to optimize the vector
*para: vector
*return: vector
*/
Vector sConstruct(Vector vtr){
Vector nVtr=new Vector();
Vector control=vtr;
if(control.size()>2)
{
String operator=vtr.get(0).toString();
nVtr.add(operator);
while (!Character.isDigit((control.get(2).toString()).charAt(0)))
{
if(control.size()>2)
{
String operand1=control.get(1).toString();
String operand2=control.get(2).toString();
String opt=((Vector)control.get(2)).get(0).toString();
if (operator.equals(opt))
{
nVtr.add(operand1);
control=(Vector)((Vector)control.get(2));
}
else
{
nVtr.add(control.get(1));
nVtr.add(control.get(2));
break;
}
}
}
}
return nVtr;
}
/*
*to evaluate the expression
*para: string
*return: double
*/
double evaluate(String str){
Vector evlt=rightConstruct(getExpr(str));
return eVector(evlt);
}
/*
*to evaluate the expression that has varibles
*para: ArgumentSet
*return: double
*/
double evaluate(ArgumentSet args){
String str=this.string;
Hashtable<String,Double> hash=args.getHash();
Enumeration enu=hash.keys();
while (enu.hasMoreElements())
{
String key=(String)enu.nextElement();
if (str.contains(key))
{
str=str.replace(key,Double.toString(args.getArgValue(key)));
}
}
return evaluate(str);
}
double eVector(Vector evlt){
double ret=0;
if (evlt.size()==0)
{
System.out.print(" no result ");
}
if (evlt.size()==1)
{
ret=Double.parseDouble(evlt.get(0).toString());
}
if(evlt.size()>=2)
{
String operator=evlt.get(0).toString();
String operand1=evlt.get(1).toString();
String operand2;
double opr1,opr2;
if (!Character.isDigit(operand1.charAt(0)))
{
opr1=eVector((Vector)evlt.get(1));
}
else
{
opr1=Double.parseDouble(operand1);
}
if(evlt.size()==3)
{
operand2=evlt.get(2).toString();
if (!Character.isDigit(operand2.charAt(0)))
{
opr2=eVector((Vector)evlt.get(2));
}
else
{
opr2=Double.parseDouble(operand2);
}
if (operator.equals("+"))
{
ret=opr1+opr2;
}
else if (operator.equals("-"))
{
ret=opr1-opr2;
}
else if (operator.equals("*"))
{
ret=opr1*opr2;
}
else if (operator.equals(