一元算子,二元表达式树和调车码算法

时间:2016-01-28 07:53:08

标签: binary-tree expression-trees shunting-yard

我正在编写数学表达式求解器,它采用中缀表达式并解决它们,二进制表达式树和分流码对我都有好处(我甚至解决了处理一元和三元运算符的问题)。遇到三角函数的问题。当我写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;
}

0 个答案:

没有答案