やりたいこと
Java
1String formula = "1 + 1"
と書いて、↓ みたいなことがしたいです。
int anser = formula //int = 2
追記
皆様ご回答ありがとうございます。
回答のロジックが理解できず、ベストアンサーを決められません。
追記
ご回答ありがとうございました。
exp4j で解決できたのでベストアンサーにさせていただきます。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
数式評価ライブラリのexp4jを試してみてはどうでしょうか。
投稿2020/06/01 11:04
編集2020/06/01 11:08総合スコア4079
0
名前呼び(call by name)
この質問のコード例が文字列としての数式であるにもかかわらず「変数に計算式を入れて」を文字どおりにとらえると、関数オブジェクトを変数に代入しておき、必要な時に関数を実行すると解釈できます。
Javaの引数は事前評価であり、実引数の評価を先に行い結果の値を仮引数に代入します。ラムダ式が導入されてから、式の評価を遅延させることができるようになりました(非正格な評価)。非正格の利点は、ラムダ式がSerializableを実装すれば分散環境にコピーして実行できることです。(そのための仕様変更がなされました)
Java
1import java.util.function.Supplier; 2 3public class ExpressionEvaluators { 4 5 static <T> Supplier<T> evaluator(Supplier<T> supplier) { 6 return () -> supplier.get(); 7 } 8 9 public static void main(String[] args) { 10 11 var exp01 = evaluator(() -> 1 + 1); 12 var exp02 = evaluator(() -> 3.0 / 5); 13 var exp03 = evaluator(() -> "Hello " + "World"); 14 15 // 遅延実行(非正格な評価) 16 var result01 = exp01.get(); 17 var result02 = exp02.get(); 18 var result03 = exp03.get(); 19 20 } 21}
Javaには存在しない名前呼び(call by name)をサポートする言語は、Supplier<T>でなく式そのものを渡すことができます。()->
の部分が不要。
投稿2020/06/02 09:18
総合スコア1090
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Java
1import java.util.regex.*; 2 3class Expr { 4 String str; int len, pos; double val; 5 char c, op[] = { '+', '-', '*', '/', '^', '^' }; 6 Pattern p = Pattern.compile("\d+\.?\d*([eE][+-]?\d+)?"); 7 8 Expr(String s) { str = s; len = s.length(); pos = 0; } 9 10 char get() { 11 while (pos < len) 12 if ((c = str.charAt(pos++)) != ' ' ) { 13 if (!Character.isDigit(c)) return c; 14 String s = str.substring(--pos); 15 Matcher m = p.matcher(s); 16 m.find(); 17 s = m.group(); 18 val = Double.parseDouble(s); 19 pos += s.length(); 20 return c = '0'; 21 } 22 return c = 0; 23 } 24 25 double expr(int i) { 26 double v; 27 if (i < 6) 28 for (v = expr(i+2); c == op[i] || c == op[i+1]; ) 29 if (c == '+') v += expr(i+2); 30 else if (c == '-') v -= expr(i+2); 31 else if (c == '*') v *= expr(i+2); 32 else if (c == '/') v /= expr(i+2); 33 else v = Math.pow(v, expr(i)); 34 else if (get() == '0') { v = val; get(); } 35 else if (c == '(') { v = expr(0); if (c == ')') get(); else c = 2; } 36 else if (c == '+') v = expr(i); 37 else if (c == '-') v = -expr(i); 38 else if (str.startsWith("sqrt(", pos-1)) { pos += 3; v = Math.sqrt(expr(i)); } 39 else v = c = 1; 40 return v; 41 } 42 43 public static void main(String[] args) { 44 String[] formulas = { 45 "1 + 2*(3 - 4)/5", 46 "355 / 113", 47 "sqrt(33^2 + 44^2)" 48 }; 49 for (String formula : formulas) { 50 Expr e = new Expr(formula); 51 double v = e.expr(0); 52 if (e.c == 0) System.out.println(formula + " = " + v); 53 else System.out.println(" Error"); 54 } 55 } 56}
追記
4つも回答をもらいながら何の応答もありませんね。
「括弧やべき乗や関数などは要らない。演算子 1個だけでよかった」
というのなら、そう言って欲しかった。
そうしたら次のようなコードを示したでしょう。
Java
1import java.util.Scanner; 2 3class Main { 4 public static void main(String[] args) { 5 String formula = "1 + 1"; 6 int answer = calc(formula); 7 System.out.println(formula + " = " + answer); 8 } 9 static int calc(String s) { 10 Scanner sc = new Scanner(s); 11 int a = sc.nextInt(); 12 String op = sc.next(); 13 int b = sc.nextInt(); 14 switch (op.charAt(0)) { 15 case '+': return a + b; 16 case '-': return a - b; 17 case '*': return a * b; 18 case '/': return a / b; 19 } 20 return 0; 21 } 22}
投稿2020/06/01 11:44
編集2020/06/05 03:56総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。