我正在编写数学表达式求解器,它采用中缀表达式并解决它们,二进制表达式树和分流码对我都有好处(我甚至解决了处理一元和三元运算符的问题)。遇到三角函数的问题。当我写45sin或(45)sin或(44 + 1)sin时,shunting-yard将其转换为有效的反向波兰表示法(RPN)并且评估成功。虽然有效的中缀表达式是sin(44 + 1)或sin45 + 1.请建议解决这个问题。
以下是ExpressionEval类的java代码,它将中缀转换为RPN。
ArticleModel
一旦我们有了修复后的表达式,评估就会在ExpressionEval类的这个函数中完成
public String infixToPostFix2(String[] expression)
{
String val = "";
if (expression == null || expression.length <= 0)
return "";
Stack<String> stack = new Stack<String>();
ArrayList<String> exp = new ArrayList<String>();
for (String token : expression)
{
if (OperatorList.isOperator(token))
{
Operator o1 = OperatorList.getOperator(token);
Operator o2 = null;
while (!stack.empty() && OperatorList.isOperator(stack.peek()))
{
o2 = OperatorList.getOperator(stack.peek());
if ( (o1.getAssociativity() == Associativity.LEFT && o1.lessThanEqual(o2))
|| (o1.getAssociativity() == Associativity.RIGHT && o1.lessThan(o2))
)
{
exp.add(stack.pop());
continue;
}
break;
}
stack.push(token);
}
else if(OperatorList.isLeftParenthesis(token))
{
stack.push(token);
}
else if (OperatorList.isRightParentheis(token))
{
while(!OperatorList.isLeftParenthesis(stack.peek()))
{
if (stack.empty())
{
this.error = Error.MISMATCHED_PARANTHESIS;
return ""; //Mismatched paranthesis
}
exp.add(stack.pop());
}
stack.pop();//Pop off the left paranthesis but not move to output
}
else //Operands
{
exp.add(token);
}
}
while(!stack.empty())
{
String s = stack.pop();
if (OperatorList.isParanthesis(s))
{
this.error = Error.MISMATCHED_PARANTHESIS;
return "";
}
exp.add(s);
}
postfixExpression = new String[exp.size()];
int index = 0;
for (String elem : exp)
{
postfixExpression[index++] = elem;
}
CalcDebug.printArray(postfixExpression);
return val;
}
运算符类与此类似。
public double evaluateExpression(String[] postfixExpression) {
CalcDebug.Debug("evaluateExpression()");
double val = 0.0;
if (postfixExpression == null || postfixExpression.length <= 0)
return val;
Stack<String> operationStack = new Stack<String>();
CalcDebug.printArray(postfixExpression);
for (String elem : postfixExpression) {
CalcDebug.Debug("elem = " + elem);
if (!OperatorList.isOperator(elem)) {
operationStack.push(elem);
} else {
double arg0 = 0.0;
double arg1 = 0.0;
double arg2 = 0.0;
OperatorType t = OperatorList.getOperatorType(elem);
if (t == OperatorType.BINARY) {
arg1 = Double.parseDouble(operationStack.pop());
arg0 = Double.parseDouble(operationStack.pop());
val = CalculatorBrain.performCalculation(elem, arg0, arg1);
} else if (t == OperatorType.UNARY) {
arg0 = Double.parseDouble(operationStack.pop());
val = CalculatorBrain.performCalculation(elem, arg0);
} else if (t == OperatorType.TERNARY) {
arg2 = Double.parseDouble(operationStack.pop());
arg1 = Double.parseDouble(operationStack.pop());
arg0 = Double.parseDouble(operationStack.pop());
val = CalculatorBrain.performCalculation(elem, arg0, arg1,
arg2);
}
operationStack.push(Double.toString(val));
}
CalcDebug.printStack(operationStack);
}
val = Double.parseDouble(operationStack.pop());
CalcDebug.Debug("val = " + val);
return val;
}