4

我正在寻找一种方法来缩短此代码并避免重复代码和 if 语句。我正在做的是创建一个计算器来搜索运算符“* / + -”的字符串并相应地执行它们。有任何想法吗?

if (exp.charAt(i) == '*') {
    newResult = Integer.parseInt(exp.substring(0, i)) * Integer.parseInt(exp.substring(i + 1, exp.length()));
    primeResult = newResult;
    System.out.println(primeResult);
} else if (exp.charAt(i) == '/') {
    newResult = Integer.parseInt(exp.substring(0, i)) / Integer.parseInt(exp.substring(i + 1, exp.length()));
    primeResult = newResult;
    System.out.println(primeResult);
} else if (exp.charAt(i) == '+') {
    newResult = Integer.parseInt(exp.substring(0, i)) + Integer.parseInt(exp.substring(i + 1, exp.length()));
    primeResult = newResult;
    System.out.println(primeResult);
} else if (exp.charAt(i) == '-') {
    newResult = Integer.parseInt(exp.substring(0, i)) - Integer.parseInt(exp.substring(i + 1, exp.length()));
    primeResult = newResult;
    System.out.println(primeResult);
}

另外,是否有解决方案可以接受具有超过 2 个操作数的字符串?即 5 + 10 * 2 / 3

4

6 回答 6

10

要更改代码,您可以使用 switch 语句并将一些冗余代码放在 switch 之前或之后。

int left = Integer.parseInt(exp.substring(0,i));
int right = Integer.parseInt(exp.substring(i+1,exp.length()));
switch(exp.charAt(i)){
    case '*':
        primeResult = left * right;
        break;
    case '/':
        ...
        break;
    case '+':
        ...
        break;
    case '-':
        ...
        break;
    default:
        ... // Error Handling.
}
System.out.println(primeResult);
于 2013-05-23T01:16:53.433 回答
6

不需要switch语句和复杂的类层次结构。

为了简化和缩短您的代码并计算简单和复杂的表达式(表示为String对象),您可以使用 JavaJavaScript API和它的ScriptEngine类,它基本上模拟了一个JavaScript控制台。

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class MyClass{
    public static void main(String[] args) throws Exception {
        // create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create a JavaScript engine
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        // evaluate JavaScript code from String
        System.out.println(engine.eval("(5+10)*2/3"));
    }
}

这将输出:10.0

于 2013-05-23T01:23:28.417 回答
4

您可以编写一个AbstractCalculationOperation带有execute方法的类,用Add,Subtract等扩展它。

然后,只需解析leftHandrightHandcalculationOperation运行calculationOperation.execute( rightHand, leftHand )

public interface CalculationOperation {
    double calculate ( double lh, double rh );
    long calculate ( long lh, long rh );
}

public class Add implements CalculationOperation {
    public static final CalculationOperation INSTANCE = new Add();
    public double calculate ( double rh, double lh ) { return lh + rh; }
    public long calculate ( long rh, long lh ) { return lh + rh; }
}

进而:

int lh = exp.substring(0, i);
int rh = exp.substring(i+1);
CalculationOperation op;
switch( exp.charAt(i) ) {
    case '*': op = Multiply.INSTANCE; break;
    case '/': op = Divide.INSTANCE; break;
    case '+': op = Add.INSTANCE; break;
    case '-': op = Subtract.INSTANCE; break;
}
newResult = op.calculate( rh, lh );
primeResult = newResult;
System.out.println(primeResult);

替代枚举变体:

public enum Calculation {
    ADD('+') {
        public int calculate( int lhs, int rhs ) { return lhs + rhs; }
        public long calculate( long lhs, long rhs ) { return lhs + rhs; }
        public float calculate( float lhs, float rhs ) { return lhs + rhs; }
        public double calculate( double lhs, double rhs ) { return lhs + rhs; }
    },
    SUBTRACT('-') {
        public int calculate( int lhs, int rhs ) { return lhs - rhs; }
        public long calculate( long lhs, long rhs ) { return lhs - rhs; }
        public float calculate( float lhs, float rhs ) { return lhs - rhs; }
        public double calculate( double lhs, double rhs ) { return lhs - rhs; }
    },
    MULTIPLY('*') {
        public int calculate( int lhs, int rhs ) { return lhs * rhs; }
        public long calculate( long lhs, long rhs ) { return lhs * rhs; }
        public float calculate( float lhs, float rhs ) { return lhs * rhs; }
        public double calculate( double lhs, double rhs ) { return lhs * rhs; }
    },
    DIVIDE('/') {
        public int calculate( int lhs, int rhs ) { return lhs / rhs; }
        public long calculate( long lhs, long rhs ) { return lhs / rhs; }
        public float calculate( float lhs, float rhs ) { return lhs / rhs; }
        public double calculate( double lhs, double rhs ) { return lhs / rhs; }
    };

    private final char textValue;
    Calculation ( char textValue )
    {
        this.textValue = textValue;
    }

    public abstract int calculate ( int lht, int rhs );
    public abstract long calculate ( long lht, long rhs );
    public abstract float calculate ( float lht, float rhs );
    public abstract double calculate ( double lht, double rhs );

    public static Calculation fromTextValue( char textValue ) {
        for( Calculation op : values() )
            if( op.textValue == textValue )
                return op;
        throw new IllegalArgumentException( "Unknown operation: " + textValue );
    }
}

进而:

int lh = exp.substring(0, i);
int rh = exp.substring(i+1);
Calculation op = Calculation.fromTextValue( exp.substring(i,1) );
newResult = op.calculate( lh, rh );
primeResult = newResult;
System.out.println(primeResult);
于 2013-05-23T01:18:31.227 回答
0

通过将变量与操作分开来缩短代码。这不会减少您的“if”语句,但会大大减少行号。

在你理解树之前不要做多个变量......我从未亲自使用过它们,但我认为“表达式树”是你所追求的。(注意:我刚刚在 google 上查看过,是的,Expression Trees)

于 2013-05-23T01:17:27.183 回答
0

如何避免过多的代码重复非常简单:

Integer op1= Integer.parseInt(exp.substring(0, i);
Integer op2=Integer.parseInt(exp.substring(i+1, exp.length()));
if(exp.charAt(i)=='*')  {
            newResult=op1 * op2;
} else 
....
primeResult = newResult;
System.out.println(primeResult);

但是要使用任意嵌套级别做一些更通用、健壮和有用的事情,你应该使用一些真正的解析器。例如。

于 2013-05-23T01:20:24.140 回答
0

这是一个片段:

public static void main(String[] args) {

        float primeResult;
        String exp = "4-2";
        int i = 1;
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");

        char[] myVar = new char[] { '*', '/', '-', '+' };

        for (int myVarCtr = 0; myVarCtr < myVar.length; myVarCtr++) {

            if (exp.charAt(i) == myVar[myVarCtr]) {

                try {
                    primeResult = Float.parseFloat(engine.eval(
                            (Integer.parseInt(exp.substring(0, i)))
                                    + Character.toString(myVar[myVarCtr])
                                    + (Integer.parseInt(exp.substring(i + 1,
                                            exp.length())))).toString());
                    System.out.println(primeResult);
                } catch (ScriptException e) {
                    e.printStackTrace();
                }

            }

        }
    }
于 2013-05-23T01:46:22.660 回答