0

ユーザーが 6 つの double を入力するプログラムがあり、プログラムは double の間に入る演算子のすべての組み合わせを 1024 の個別の文字列として出力します。ユーザーが 14、17、200、1、5、および 118 を入力した場合の最初の 2 つの結果を次に示します。

"14.0+17.0+200.0+1.0+5.0+118.0"

"14.0+17.0+200.0+1.0+5.0-118.0"

私がやりたいのは、演算の順序に従って演算を実行することです。各 double は変数 a から f として格納され、これらの変数の間の各演算子は char a_b から e_f として格納されます。そう:

    double a, b, c, d, e, f;
    char a_b, b_c, c_d, d_e, e_f;

私が最初に考えたのは、次のようなコードを書くことでした。

    public double operateGroup() {
    value = 0;

    switch (a_b) {
    case '+':
        value += a + b;
        break;
    case '-':
        value += a - b;
        break;
    case '*':
        value += a * b;
        break;
    case '/':
        value += a / b;
        break;
    default:
        break;
    }

    switch (b_c) {
    case '+':
        value += c;
        break;
    case '-':
        value += -c;
        break;
    case '*':
        value *= c;
        break;
    case '/':
        value /= c;
        break;
    default:
        break;
    }

    switch (c_d) {
    case '+':
        value += d;
        break;
    case '-':
        value += -d;
        break;
    case '*':
        value *= d;
        break;
    case '/':
        value /= d;
        break;
    default:
        break;
    }

    switch (d_e) {
    case '+':
        value += e;
        break;
    case '-':
        value += -e;
        break;
    case '*':
        value *= e;
        break;
    case '/':
        value /= e;
        break;
    default:
        break;
    }

    switch (e_f) {
    case '+':
        value += f;
        break;
    case '-':
        value += -f;
        break;
    case '*':
        value *= f;
        break;
    case '/':
        value /= f;
        break;
    default:
        break;
    }

    return value;
}

しかし、これは (a O b) O c) O d) O e) を実行するのと同じであるため、機能しません。ここで、O は任意の演算子です。任意のヒント?

4

3 に答える 3

2

括弧がないため、単純なアプローチが機能します。

  • 乗算と除算を処理するために、リストを 1 回調べます。
  • X と Y の間の演算子がまたはの場合、*または/に置き換えX、Y を削除します。演算子も削除しますX*YX/Y
  • リストをもう一度見てみましょう。今回は加算と減算を順番に処理します。

このアプローチを実装するには、2 つのリスト ( のリストN DoubleN-1演算子) を定義し、次のように計算を実装します。

ArrayList<Double> vals = ...
ArrayList<Integer> ops = ... // 1=+, 2=-, 3=*, 4=/
for (int i = 0 ; i < ops.Count ; i++) {
    int op = ops.get(i);
    if (op == 3 || op == 4) {
        if (op == 3) {
            vals.set(i, vals.get(i) * vals.get(i+1));
        } else {
            vals.set(i, vals.get(i) / vals.get(i+1));
        }
        ops.remove(i);
        vals.remove(i+1);
        i--;
    }
}
double res = vals.get(0);
for (int i = 0 ; i != ops.Count ; i++) {
    if (op == 1) {
        res += vals.get(i);
    } else {
        res -= vals.get(i);
    }
}
于 2013-05-19T02:13:48.637 に答える
1

演算子とオペランドの情報が必要な場合は、解析ツリーを構築する必要があります(これは以前に尋ねられました)。

結果のみに関心がある場合は、String直接評価できます。

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Eval {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager s = new ScriptEngineManager();
        ScriptEngine engine = s.getEngineByName("JavaScript");
        String exp = "14.0+17.0+200.0+1.0+5.0-118.0";
        System.out.println(engine.eval(exp));
    }    
}

出力:

119.0
于 2013-05-19T02:14:33.483 に答える
0

それをツリーに解析してから、ツリーをたどって評価する必要があると思います。数値は葉ノードで、演算子は親です。

于 2013-05-19T02:12:56.703 に答える