📄 addexpression.java
字号:
* @param tok
* the infix operator
* @exception Exception
* if there is difficulty parsing the operator
*/
private void handleOperator(String tok) throws Exception {
boolean push = true;
char tokchar = tok.charAt(0);
if (tokchar == ')') {
String popop = " ";
do {
popop = (String) (m_operatorStack.pop());
if (popop.charAt(0) != '(') {
m_postFixExpVector
.addElement(new Operator(popop.charAt(0)));
}
} while (popop.charAt(0) != '(');
} else {
int infixToc = infixPriority(tok.charAt(0));
while (!m_operatorStack.empty()
&& stackPriority(((String) (m_operatorStack.peek()))
.charAt(0)) >= infixToc) {
// try an catch double operators and see if the current one can
// be interpreted as the sign of an upcoming number
if (m_previousTok.length() == 1
&& isOperator(m_previousTok.charAt(0))
&& m_previousTok.charAt(0) != ')') {
if (tok.charAt(0) == '-') {
m_signMod = true;
} else {
m_signMod = false;
}
push = false;
break;
} else {
String popop = (String) (m_operatorStack.pop());
m_postFixExpVector
.addElement(new Operator(popop.charAt(0)));
}
}
if (m_postFixExpVector.size() == 0) {
if (tok.charAt(0) == '-') {
m_signMod = true;
push = false;
}
}
if (push) {
m_operatorStack.push(tok);
}
}
}
/**
* Converts a string containing a mathematical expression in infix form to
* postfix form. The result is stored in the vector m_postfixExpVector
*
* @param infixExp
* the infix expression to convert
* @exception Exception
* if something goes wrong during the conversion
*/
private void convertInfixToPostfix(String infixExp) throws Exception {
//<<tyleung 22/03/2005
validateOperator(infixExp);
//tyleung 22/03/2005>>
infixExp = Utils.removeSubstring(infixExp, " ");
infixExp = Utils.replaceSubstring(infixExp, "log", "l");
infixExp = Utils.replaceSubstring(infixExp, "abs", "b");
infixExp = Utils.replaceSubstring(infixExp, "cos", "c");
infixExp = Utils.replaceSubstring(infixExp, "exp", "e");
infixExp = Utils.replaceSubstring(infixExp, "sqrt", "s");
infixExp = Utils.replaceSubstring(infixExp, "floor", "f");
infixExp = Utils.replaceSubstring(infixExp, "ceil", "h");
infixExp = Utils.replaceSubstring(infixExp, "rint", "r");
infixExp = Utils.replaceSubstring(infixExp, "tan", "t");
infixExp = Utils.replaceSubstring(infixExp, "sin", "n");
//<<Frank Xu, 09/09/2004
//Add relational operators.
infixExp = Utils.replaceSubstring(infixExp, "eq", "u");
infixExp = Utils.replaceSubstring(infixExp, "ne", "v");
infixExp = Utils.replaceSubstring(infixExp, "ge", "w");
infixExp = Utils.replaceSubstring(infixExp, "gt", "x");
infixExp = Utils.replaceSubstring(infixExp, "le", "y");
infixExp = Utils.replaceSubstring(infixExp, "lt", "z");
//Frank Xu, 09/09/2004>>
StringTokenizer tokenizer = new StringTokenizer(infixExp, OPERATORS,
true);
m_postFixExpVector = new Vector();
while (tokenizer.hasMoreTokens()) {
String tok = tokenizer.nextToken();
if (tok.length() > 1) {
handleOperand(tok);
} else {
// probably an operator, but could be a single char operand
if (isOperator(tok.charAt(0))) {
handleOperator(tok);
} else {
// should be a numeric constant
handleOperand(tok);
}
}
m_previousTok = tok;
}
while (!m_operatorStack.empty()) {
String popop = (String) (m_operatorStack.pop());
if (popop.charAt(0) == '(' || popop.charAt(0) == ')') {
throw new Exception("Mis-matched parenthesis!");
}
m_postFixExpVector.addElement(new Operator(popop.charAt(0)));
}
}
/**
* Evaluate the expression using the supplied array of attribute values. The
* result is stored in the last element of the array. Assumes that the infix
* expression has been converted to postfix and stored in m_postFixExpVector
*
* @param vals
* the values to apply the expression to
* @exception Exception
* if something goes wrong
*/
private void evaluateExpression(double[] vals) throws Exception {
Stack operands = new Stack();
for (int i = 0; i < m_postFixExpVector.size(); i++) {
Object nextob = m_postFixExpVector.elementAt(i);
if (nextob instanceof NumericOperand) {
operands.push(new Double(
((NumericOperand) nextob).m_numericConst));
} else if (nextob instanceof AttributeOperand) {
double value = vals[((AttributeOperand) nextob).m_attributeIndex];
if (value == Instance.missingValue()) {
vals[vals.length - 1] = Instance.missingValue();
break;
}
if (((AttributeOperand) nextob).m_negative) {
value = -value;
}
operands.push(new Double(value));
} else if (nextob instanceof Operator) {
char op = ((Operator) nextob).m_operator;
if (isUnaryFunction(op)) {
double operand = ((Double) operands.pop()).doubleValue();
double result = ((Operator) nextob).applyFunction(operand);
operands.push(new Double(result));
} else {
double second = ((Double) operands.pop()).doubleValue();
double first = ((Double) operands.pop()).doubleValue();
double result = ((Operator) nextob).applyOperator(first,
second);
operands.push(new Double(result));
}
} else {
throw new Exception("Unknown object in postfix vector!");
}
}
if (operands.size() != 1) {
throw new Exception("Problem applying function");
}
Double result = ((Double) operands.pop());
if (result.isNaN() || result.isInfinite()) {
vals[vals.length - 1] = Instance.missingValue();
} else {
vals[vals.length - 1] = result.doubleValue();
}
}
/**
* Returns true if a token is an operator
*
* @param tok
* the token to check
* @return true if the supplied token is an operator
*/
private boolean isOperator(char tok) {
if (OPERATORS.indexOf(tok) == -1) {
return false;
}
return true;
}
/**
* Returns true if a token is a unary function
*
* @param tok
* the token to check
* @return true if the supplied token is a unary function
*/
private boolean isUnaryFunction(char tok) {
if (UNARY_FUNCTIONS.indexOf(tok) == -1) {
return false;
}
return true;
}
/**
* Return the infix priority of an operator
*
* @param char
* the operator
* @return the infix priority
*/
private int infixPriority(char opp) {
switch (opp) {
case 'l':
case 'b':
case 'c':
case 'e':
case 's':
case 'f':
case 'h':
case 'r':
case 't':
case 'n':
//<<Frank Xu, add relational operators. 09/09/2004
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
//Frank Xu>>
return 3;
case '^':
return 2;
case '*':
return 2;
case '/':
return 2;
case '+':
return 1;
case '-':
return 1;
case '(':
return 4;
case ')':
return 0;
default:
throw new IllegalArgumentException("Unrecognized operator:" + opp);
}
}
/**
* Return the stack priority of an operator
*
* @param char
* the operator
* @return the stack priority
*/
private int stackPriority(char opp) {
switch (opp) {
case 'l':
case 'b':
case 'c':
case 'e':
case 's':
case 'f':
case 'h':
case 'r':
case 't':
case 'n':
//<<Frank Xu, add relational operators. 09/09/2004
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
// Frank Xu>>
return 3;
case '^':
return 2;
case '*':
return 2;
case '/':
return 2;
case '+':
return 1;
case '-':
return 1;
case '(':
return 0;
case ')':
return -1;
default:
throw new IllegalArgumentException("Unrecognized operator:" + opp);
}
}
/**
* Returns an enumeration describing the available options.
*
* @return an enumeration of all the available options.
*/
public Enumeration listOptions() {
Vector newVector = new Vector(3);
newVector
.addElement(new Option(
"\tSpecify the expression to apply. Eg a1^2*a5/log(a7*4.0)."
+ "\n\tSupported opperators: ,+, -, *, /, ^, log, abs, cos, "
+ "\n\teq, ne, ge, gt, le, lt"//Frank Xu, add
// relational
// operators
+ "\n\texp, sqrt, floor, ceil, rint, tan, sin, (, )",
"E", 1, "-E <expression>"));
newVector.addElement(new Option(
"\tSpecify the name for the new attribute. (default is the "
+ "expression provided with -E)", "N", 1, "-N <name>"));
newVector.addElement(new Option(
"\tDebug. Names attribute with the postfix parse of the "
+ "expression.", "D", 0, "-D"));
return newVector.elements();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -