Java string-type equation double digit value issue

这一生的挚爱 提交于 2019-12-11 05:16:21

问题


I've been assigned to create a Java program which reads a string equation and calculates its value. But the code I've managed to create this far is only able to calculate single-digit integers. And I have no idea how to make my longer length integers work. What should my function look like in order to work with double or even triple digit integers?

public class Ex8 {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

    String e =  "1 - 3 * 18 / 4 + 2";
    double t = executeStringEquation(e);
    System.out.println(e + " = "+t);
    }



      public static double executeStringEquation(String inputEquation)
      {
        if("".equals(inputEquation))
        {
            return 0;
        }
        else if(inputEquation.length() == 1)
        {
            return Integer.valueOf(inputEquation);
        }

        else
        {
            String _a = String.valueOf(inputEquation.charAt(0));
            String _b = String.valueOf(inputEquation.charAt(1));
            if("+".equals(_b) || "-".equals(_b) )
            {
                if("+".equals(_b))
                {
                    return Integer.valueOf(_a) + executeStringEquation(inputEquation.substring(2));
                }
                else
                {// "-"
                    return Integer.valueOf(_a) - executeStringEquation(inputEquation.substring(2));
                }
            }
            else
            {// "*" or "/"
                boolean isMulti = ("*".equals(_b));
                String  _c = String.valueOf(inputEquation.charAt(2));                
                Integer tmp = 0;
                if(isMulti)
                {
                    tmp = Integer.valueOf(_a) * Integer.valueOf(_c);
                }
                else
                {
                    tmp = Integer.valueOf(_a) / Integer.valueOf(_c);
                }
                String newStr = String.valueOf(tmp) + inputEquation.substring(3);                
                return executeStringEquation(newStr);
            }
        }
    }
}

回答1:


I'm developing a function to evaluate your expressions with postfix evaluation for multidigit numbers. The idea to do it is the Postfix and Infix notation that you can read here: http://interactivepython.org/runestone/static/pythonds/BasicDS/InfixPrefixandPostfixExpressions.html

Here is the piece of code for this task. I corrected the bug on the expression evaluator and now the evaluation is correct, please check it out:

package com.stackoverflow.infix;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;

public class InfixPostfixEvaluator {

    private static final String operators = "-+/*";

    private int getPrecedence(String input) {
        char operator = input.charAt(0);
        int ret = 0;
        if (operator == '-' || operator == '+') {
            ret = 1;
        } else if (operator == '*' || operator == '/') {
            ret = 2;
        }
        return ret;
    }

    private boolean operatorGreaterOrEqual(String op1, String op2) {
        return getPrecedence(op1) >= getPrecedence(op2);
    }

    private boolean isOperator(String operator) {
        return operators.indexOf(operator) >= 0;
    }

    private boolean isOperand(String val) {
        try {
            Double.parseDouble(val);
        } catch (NumberFormatException nfe) {
            return false;
        }
        return true;
    }

    public Stack<String> convert2Postfix(List<String> expressionInTokens) {
        Stack<String> stack = new Stack<String>();
        Stack<String> postExpression = new Stack<String>();

        for (String c : expressionInTokens) {
            if (isOperator(c)) {
                while (!stack.isEmpty()) {
                    if (operatorGreaterOrEqual(stack.peek(), c)) {
                        postExpression.push(stack.pop());
                    } else {
                        break;
                    }
                }
                stack.push(c);
            } else if (isOperand(c)) {
                postExpression.push(c);
            }
        }
        while(!stack.isEmpty()){
            postExpression.push(stack.pop());
        }
        Collections.reverse(postExpression);
        return postExpression;
    }

    public int evaluatePostfix(Stack<String> expression) {
        Stack<Integer> stack = new Stack<Integer>();
        while (!expression.isEmpty()) {
            String c = expression.pop();
            if (isOperand(String.valueOf(c))) {
                stack.push(Integer.parseInt(c));
            } else if (isOperator(String.valueOf(c))) {
                int op1 = stack.pop();
                int op2 = stack.pop();
                int result;
                switch (c) {
                case "*":
                    result = op1 * op2;
                    stack.push(result);
                    break;
                case "/":
                    result = op2 / op1;
                    stack.push(result);
                    break;
                case "+":
                    result = op1 + op2;
                    stack.push(result);
                    break;
                case "-":
                    result = op2 - op1;
                    stack.push(result);
                    break;
                }
            }
        }
        return stack.pop();
    }

    /**
     * Takes an expression and parses it, returning a list with every element of
     * the expression.The expression must not have white spaces, or characters
     * different from numbers or the operands + - / *
     * 
     */
    public List<String> split(String expression) {
        List<String> a = new LinkedList<String>();

        StringTokenizer st = new StringTokenizer(expression, "+*/-", true);
        while (st.hasMoreTokens())
            a.add(st.nextToken());
        return a;
    }

}

And the tests

package com.stackoverflow.infix;

import static org.junit.Assert.assertEquals;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;

import org.junit.Test;

public class TestInfixPostfixEvaluator {

    @Test
    public void testWhole() {

        InfixPostfixEvaluator eval = new InfixPostfixEvaluator();

        String infixExpr = "5+50-10";
        List<String> expression = eval.split(infixExpr);
        Stack<String> stack = eval.convert2Postfix(expression);
        assertEquals(45, eval.evaluatePostfix(stack));

        infixExpr = "2-3+4";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(3, eval.evaluatePostfix(stack));

        infixExpr = "305-303+4";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(6, eval.evaluatePostfix(stack));

        infixExpr = "2+3";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(5, eval.evaluatePostfix(stack));

        infixExpr = "2*5+5";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(15, eval.evaluatePostfix(stack));

        infixExpr = "2*5/5*5";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(10, eval.evaluatePostfix(stack));

        infixExpr = "4+2*16/4";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(12, eval.evaluatePostfix(stack));

        infixExpr = "16*3/4+2";
        expression = eval.split(infixExpr);
        stack = eval.convert2Postfix(expression);
        assertEquals(14, eval.evaluatePostfix(stack));

    }

    @Test
    public void testSplit() {
        String exp = "15+20+84/205-1";
        LinkedList<String> a = new LinkedList<String>();

        StringTokenizer st = new StringTokenizer(exp, "+*/-", true);
        while (st.hasMoreTokens())
            a.add(st.nextToken());
        System.out.println(a.toString());
    }

}



回答2:


Consider reading in the whole string and splitting on white space. That might not be a valid parsing rule, but it will allow you to get multi digit integers.



来源:https://stackoverflow.com/questions/42817854/java-string-type-equation-double-digit-value-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!