问题
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