以字符串格式评估随机生成的数学方程式,并得到答案


public class Test {
    static Random rand = new Random();
    String operators = "+-*/";
    public static char getRandomOperator() {
        return operators.charAt(rand.nextInt(operators.length()));
    }
    Random rand = new Random();
    int a = rand.nextInt(5) + 1;
    int b = rand.nextInt(5) + 1;
    String equation = "";
    equation += a;
    equation += getRandomOperator();
    equation += b;
    equation += getRandomOperator();
    equation += c;
}

在此代码中,请考虑我获得等式= 2 3*4,该格式为字符串格式。我应该如何评估它并在整数中获得答案。我不能使用JavaScript,因为我在Android应用中使用了此代码。

基本上这是表达评估问题。您可以通过了解运营商的优先顺序来解决它。当括号时,这可能会变得复杂。您还需要使用堆栈才能解决这些表达式。可以在这里找到答案。

很多程序员都害怕这种事情,并且有一个复杂的方法。

我为自己做了足够的时间终于以一种非常简单的方式来实施它而感到自豪。这是您的4个操作员的实现,但它很容易扩展以涵盖更优先级别的级别,一元操作员,括号和功能。

关键是evaluateNext(int minPrec)方法的签名,它提供了一种非常方便的方法,将问题分为等效的子问题:

import java.util.HashMap;
import java.util.regex.*;
public class Calculator {
    private static final Pattern TERM_AND_OP_PATTERN = Pattern.compile("([^0-9a-zA-Z]*[0-9a-zA-Z\.]+\s*)([-+\*\/])");
    private static final HashMap<String, Integer> PRECS = new HashMap<>();
    {
        PRECS.put("+",0);
        PRECS.put("-",0);
        PRECS.put("*",1);
        PRECS.put("/",1);
    }
    String m_input;
    int m_currentPos;
    //points at the next operator, or null if none
    Matcher m_matcher;
    public synchronized double evalutate(String expression) throws Exception
    {
        m_input = expression;
        m_currentPos = 0;
        m_matcher = TERM_AND_OP_PATTERN.matcher(m_input);
        if (!m_matcher.find())
        {
            m_matcher = null;
        }
        try
        {
            return _evaluateNext(-1);
        }
        finally
        {
            m_input = null;
            m_matcher = null;
        }
    }
    //Evaluate the next sub-expression, including operators with
    //precedence >= minPrec
    private double _evaluateNext(int minPrec) throws Exception
    {
        double val;
        if (m_matcher == null)
        {
            val = Double.parseDouble(m_input.substring(m_currentPos).trim());
        }
        else
        {
            val = Double.parseDouble(m_matcher.group(1).trim());
        }
        while(m_matcher != null)
        {
            String op = m_matcher.group(2);
            //get and check precedence of the next operator
            Integer curPrec = PRECS.get(op);
            if (curPrec == null)
            {
                curPrec = 0;
            }
            if (curPrec<minPrec)
            {
                //our subexpression ends here
                return val;
            }
            //advance to next term/op
            m_currentPos = m_matcher.end();
            if (!m_matcher.find())
            {
                m_matcher = null;
            }
            switch(op)
            {
                case "+":
                    val += _evaluateNext(curPrec+1);
                    break;
                case "-":
                    val -= _evaluateNext(curPrec+1);
                    break;
                case "*":
                    val *= _evaluateNext(curPrec+1);
                    break;
                case "/":
                    val /= _evaluateNext(curPrec+1);
                    break;
            }
        }
        //found end of the expression
        return val;
    }

    public static void test(String expr) throws Exception
    {
        System.out.printf("%s = %fn", expr, new Calculator().evalutate(expr));
    }

    public static void main(String[] args) throws Exception
    {
        test("8*2-1*4");
        test(" 8 * 2 - 1 * 4 ");
        test("-5 + -1 /2");
        test("223.3");
        test("223.3*2");
    }
}

最新更新