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ステートメントやクラスの複雑な階層は必要ありません。

コードを簡素化および短縮し、単純および複雑な式 (オブジェクトとして表される) を計算するために、基本的にコンソールをシミュレートするStringJavaJavaScript APIおよびそのクラスを使用できます。ScriptEngineJavaScript

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クラスを作成できます。executeAddSubtract

leftHand次に、 、rightHand、およびを解析calculationOperationして実行します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」ステートメントが減ることはありませんが、行数が大幅に減ります。

ツリーを理解するまでは、複数の変数を使用しないでください... 個人的にそれらを扱ったことはありませんが、「式ツリー」はあなたが求めているものだと思います。(注:私はグーグルでチェックしました、はい、式ツリー)

于 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 に答える