স্ট্রিং আকারে দেওয়া গণিতের এক্সপ্রেশনকে কীভাবে মূল্যায়ন করবেন?


318

আমি এই জাতীয় Stringমানগুলি থেকে সাধারণ গণিতের প্রকাশগুলি মূল্যায়নের জন্য একটি জাভা রুটিন লেখার চেষ্টা করছি :

  1. "5+3"
  2. "10-40"
  3. "10*3"

আমি-তবে-অন্য বিবৃতিগুলি অনেক এড়াতে চাই। কিভাবে আমি এটি করতে পারব?


7
আমি সম্প্রতি এক্সপ 4 জে নামে একটি গণিতের এক্সপ্রেশন পার্সার লিখেছি যা অ্যাপাচি লাইসেন্সের আওতায় প্রকাশিত হয়েছে আপনি এটি এখানে দেখতে পারেন: objecthunter.net/exp4j
fasseg

2
আপনি কোন ধরণের অভিব্যক্তির অনুমতি দেন? শুধুমাত্র একক অপারেটর এক্সপ্রেশন? বন্ধনী অনুমোদিত?
রায়েডওয়াল্ড



3
এটি কীভাবে খুব বেশি বিস্তৃত হিসাবে বিবেচনা করা যেতে পারে? Dijkstra এর মূল্যায়ন সুস্পষ্ট সমাধান এখানে en.wikipedia.org/wiki/Shunting-yard_algorithm
মার্টিন Spamer

উত্তর:


376

JDK1.6 এর সাহায্যে আপনি অন্তর্নির্মিত জাভাস্ক্রিপ্ট ইঞ্জিনটি ব্যবহার করতে পারেন।

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

public class Test {
  public static void main(String[] args) throws ScriptException {
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    String foo = "40+2";
    System.out.println(engine.eval(foo));
    } 
}

52
মনে হচ্ছে সেখানে একটি বড় সমস্যা আছে; এটি একটি স্ক্রিপ্ট কার্যকর করে, কোনও এক্সপ্রেশনকে মূল্যায়ন করে না। পরিষ্কার হওয়ার জন্য, ইঞ্জিন.ইভাল ("8; 40 + 2"), আউটপুটস 42! আপনি যদি এমন একটি এক্সপ্রেশন পার্সার চান যা এটি সিনট্যাক্সটিও পরীক্ষা করে, আমি সবেমাত্র একটি শেষ করেছি (কারণ আমি আমার প্রয়োজন অনুসারে এমন কিছু পাইনি ): জাভালুয়েটর
জিন-মার্ক অ্যাসেটসানা

4
পার্শ্ব নোট হিসাবে, আপনি যদি নিজের কোডে এই অভিব্যক্তিটির ফলাফল অন্য কোথাও ব্যবহার করতে চান তবে আপনি ফলাফলটি দ্বিগুণ পছন্দ করতে পারেন: return (Double) engine.eval(foo);
বেন ভিসনেস

38
সুরক্ষা নোট: আপনার ব্যবহারকারীর ইনপুট সহ কোনও সার্ভারের প্রসঙ্গে এটি ব্যবহার করা উচিত নয়। কার্যকর করা জাভাস্ক্রিপ্ট সমস্ত জাভা ক্লাস অ্যাক্সেস করতে পারে এবং এভাবে সীমা ছাড়াই আপনার অ্যাপ্লিকেশন হাইজ্যাক করতে পারে।
বোয়ান

3
@ বনান, আমি আপনাকে অনুরোধ করছি আপনি যা বলেছিলেন সে সম্পর্কে আমাকে একটি রেফারেন্স দিন। (নিশ্চিতভাবেই 100%)
পার্থো

17
@ পার্থো new javax.script.ScriptEngineManager().getEngineByName("JavaScript") .eval("var f = new java.io.FileWriter('hello.txt'); f.write('UNLIMITED POWER!'); f.close();");- জাভাস্ক্রিপ্টের মাধ্যমে একটি ফাইল লিখবে (ডিফল্টরূপে) প্রোগ্রামটির বর্তমান ডিরেক্টরি
বোয়ান

236

evalএই প্রশ্নের উত্তর দেওয়ার জন্য আমি পাটিগণিতের প্রকাশের জন্য এই পদ্ধতিটি লিখেছি । এটি সংযোজন, বিয়োগ, গুণ, বিভাজন, ক্ষয়ক্ষেত্র ( ^প্রতীক ব্যবহার করে ) এবং কয়েকটি প্রাথমিক ফাংশন করে sqrt। এটি ব্যবহার গোষ্ঠীবদ্ধ সমর্থন (... ), এবং এটি অপারেটর পায় প্রাধান্য এবং associativity সঠিক নিয়ম।

public static double eval(final String str) {
    return new Object() {
        int pos = -1, ch;

        void nextChar() {
            ch = (++pos < str.length()) ? str.charAt(pos) : -1;
        }

        boolean eat(int charToEat) {
            while (ch == ' ') nextChar();
            if (ch == charToEat) {
                nextChar();
                return true;
            }
            return false;
        }

        double parse() {
            nextChar();
            double x = parseExpression();
            if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
            return x;
        }

        // Grammar:
        // expression = term | expression `+` term | expression `-` term
        // term = factor | term `*` factor | term `/` factor
        // factor = `+` factor | `-` factor | `(` expression `)`
        //        | number | functionName factor | factor `^` factor

        double parseExpression() {
            double x = parseTerm();
            for (;;) {
                if      (eat('+')) x += parseTerm(); // addition
                else if (eat('-')) x -= parseTerm(); // subtraction
                else return x;
            }
        }

        double parseTerm() {
            double x = parseFactor();
            for (;;) {
                if      (eat('*')) x *= parseFactor(); // multiplication
                else if (eat('/')) x /= parseFactor(); // division
                else return x;
            }
        }

        double parseFactor() {
            if (eat('+')) return parseFactor(); // unary plus
            if (eat('-')) return -parseFactor(); // unary minus

            double x;
            int startPos = this.pos;
            if (eat('(')) { // parentheses
                x = parseExpression();
                eat(')');
            } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
                while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
                x = Double.parseDouble(str.substring(startPos, this.pos));
            } else if (ch >= 'a' && ch <= 'z') { // functions
                while (ch >= 'a' && ch <= 'z') nextChar();
                String func = str.substring(startPos, this.pos);
                x = parseFactor();
                if (func.equals("sqrt")) x = Math.sqrt(x);
                else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
                else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
                else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
                else throw new RuntimeException("Unknown function: " + func);
            } else {
                throw new RuntimeException("Unexpected: " + (char)ch);
            }

            if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation

            return x;
        }
    }.parse();
}

উদাহরণ:

System.out.println(eval("((4 - 2^3 + 1) * -sqrt(3*3+4*4)) / 2"));

আউটপুট: 7.5 (যা সঠিক)


পার্সার একটি পুনরাবৃত্তীয় বংশদ্ভুত পার্সার , সুতরাং অভ্যন্তরীণভাবে এর ব্যাকরণে প্রতিটি স্তরের অপারেটরের অগ্রাধিকারের জন্য পৃথক বিশ্লেষণ পদ্ধতি ব্যবহার করে। আমি এটিকে সংক্ষিপ্ত করে রেখেছি যাতে এটি পরিবর্তন করা সহজ তবে আপনি এখানে কিছু ধারণা দিতে পারেন যার সাথে এটি প্রসারিত করতে পারেন:

  • ভেরিয়েবল:

    ফাংশনগুলির জন্য নামগুলি পড়ার পার্সারের বিটটি কাস্টম ভেরিয়েবলগুলি পরিচালনা করতে খুব সহজেই পরিবর্তিত হতে পারে, evalপদ্ধতিতে পাস হওয়া ভেরিয়েবল সারণিতে নাম সন্ধান করে Map<String,Double> variables

  • সংকলন এবং মূল্যায়ন পৃথক করুন:

    যদি, ভেরিয়েবলগুলির জন্য সমর্থন যোগ করে, আপনি প্রতিবার পার্স না করে পরিবর্তিত ভেরিয়েবলের সাথে একই অভিব্যক্তি কয়েক মিলিয়ন বার মূল্যায়ন করতে চেয়েছিলেন? এটা সম্ভব. পূর্ববর্তী কম্পাইল এক্সপ্রেশন মূল্যায়নের জন্য প্রথমে একটি ইন্টারফেস সংজ্ঞায়িত করুন:

    @FunctionalInterface
    interface Expression {
        double eval();
    }

    এখন ফিরে আসা সমস্ত পদ্ধতিগুলি পরিবর্তন করুন double, সুতরাং পরিবর্তে তারা সেই ইন্টারফেসের একটি উদাহরণ ফিরে আসে। জাভা 8 এর ল্যাম্বদা সিনট্যাক্স এটির জন্য দুর্দান্ত কাজ করে। পরিবর্তিত পদ্ধতির একটি উদাহরণ:

    Expression parseExpression() {
        Expression x = parseTerm();
        for (;;) {
            if (eat('+')) { // addition
                Expression a = x, b = parseTerm();
                x = (() -> a.eval() + b.eval());
            } else if (eat('-')) { // subtraction
                Expression a = x, b = parseTerm();
                x = (() -> a.eval() - b.eval());
            } else {
                return x;
            }
        }
    }

    Expressionএটি সংকলিত অভিব্যক্তি (একটি বিমূর্ত সিনট্যাক্স ট্রি ) উপস্থাপন করে এমন একটি পুনরাবৃত্ত গাছ তৈরি করে । তারপরে আপনি এটি একবার সংকলন করতে এবং বিভিন্ন মান সহ বারবার মূল্যায়ন করতে পারেন:

    public static void main(String[] args) {
        Map<String,Double> variables = new HashMap<>();
        Expression exp = parse("x^2 - x + 2", variables);
        for (double x = -20; x <= +20; x++) {
            variables.put("x", x);
            System.out.println(x + " => " + exp.eval());
        }
    }
  • বিভিন্ন ডেটাটাইপ:

    পরিবর্তে double, আপনি মূল্যবানকে আরও শক্তিশালী কিছু ব্যবহার করতে BigDecimalবা এমন একটি শ্রেণি যা জটিল সংখ্যা, বা যুক্তিযুক্ত সংখ্যা (ভগ্নাংশ) প্রয়োগ করে change এমনকি আপনি Objectবাস্তব প্রোগ্রামিং ভাষার মতোই অভিব্যক্তিগুলিতে ডেটাটাইপগুলির কিছু মিশ্রণ ব্যবহার করে এমনকি ব্যবহার করতে পারেন । :)


এই উত্তরের সমস্ত কোড পাবলিক ডোমেনে প্রকাশিত হয়েছে । আনন্দ কর!


1
চমৎকার অ্যালগরিদম, এটি থেকে শুরু করে আমি ইমপ্লিমেন্ট এবং লজিকাল অপারেটরগুলিতে পরিচালনা করেছিলাম। কোনও ফাংশনকে মূল্যায়ন করার জন্য আমরা ফাংশনগুলির জন্য পৃথক ক্লাস তৈরি করেছি, সুতরাং আপনার ভেরিয়েবলগুলির ধারণার মতো, আমি ফাংশন এবং ফাংশনটির নাম অনুসন্ধান করে একটি মানচিত্র তৈরি করি। প্রতিটি ফাংশন একটি পদ্ধতি ইওল (টি রাইটওপ্রেটার, টি বাম অপারেটার) সহ একটি ইন্টারফেস প্রয়োগ করে, তাই যে কোনও সময় আমরা অ্যালগরিদম কোডটি পরিবর্তন না করে বৈশিষ্ট্যগুলি যুক্ত করতে পারি। এবং এটিকে জেনেরিক ধরণের সাথে কাজ করা ভাল ধারণা idea আপনাকে ধন্যবাদ!
ভ্যাসাইল বোর্স

1
আপনি কি এই অ্যালগরিদমের পিছনে যুক্তি ব্যাখ্যা করতে পারেন?
আইওনাটান

1
বোয়ান রচিত কোড থেকে আমি কী বুঝি তার একটি বিবরণ দেওয়ার চেষ্টা করি এবং উদাহরণগুলি উইকি বর্ণিত। অপারেশন আদেশের বিধি থেকে শুরু করে এই অ্যালগরিটমের যুক্তি। 1. অপারেটর সাইন | পরিবর্তনশীল মূল্যায়ন | ফাংশন কল | প্রথম বন্ধনী (উপ-এক্সপ্রেশন); 2. ক্ষয়ক্ষতি; 3. গুণ, বিভাগ; 4. সংযোজন, বিয়োগ;
ভ্যাসিল বোর্স

1
অ্যালগরিদম পদ্ধতিগুলি প্রতিটি স্তরের ক্রিয়াকলাপ ক্রমের জন্য নিম্নরূপে বিভক্ত: পার্সফ্যাক্টর = ১ অপারেটর সাইন পরিবর্তনশীল মূল্যায়ন | ফাংশন কল | প্রথম বন্ধনী (উপ-এক্সপ্রেশন); 2. ক্ষয়ক্ষতি; parseTerms = 3. গুণ, বিভাগ; parseExpression = 4. যোগ, বিয়োগফল। অ্যালগরিদম, বিপরীত ক্রমে কল পদ্ধতি (parseExpression -> parseTerms -> parseFactor -> parseExpression (উপ-এক্সপ্রেশনগুলির জন্য)), তবে প্রথম লাইনের প্রতিটি পদ্ধতিই পদ্ধতিটিকে পরবর্তী স্তরে কল করে, সুতরাং সম্পূর্ণ কার্যকর আদেশের পদ্ধতিগুলি হবে অপারেশন আসলে স্বাভাবিক ক্রম।
ভ্যাসিল বারস

1
উদাহরণস্বরূপ পার্সএক্সপ্রেসনের পদ্ধতিটি double x = parseTerm(); বাম অপারেটরকে মূল্যায়ন করে, এর পরে for (;;) {...}প্রকৃত অর্ডার স্তরের সফল সংযোজনগুলি (সংযোজন, বিয়োগফল) মূল্যায়ন করে। একই যুক্তিটি হল এবং পার্সেটার্ম পদ্ধতিতে। পার্সফ্যাক্টরের পরবর্তী স্তর নেই, সুতরাং কেবল পদ্ধতি / পরিবর্তনশীল বা প্যারান্থেসিসের ক্ষেত্রে মূল্যায়ন রয়েছে - উপ-এক্সপ্রেশনটি মূল্যায়ন করুন। boolean eat(int charToEat)CharToEat অক্ষর দিয়ে বর্তমান কার্সার চরিত্রের পদ্ধতি চেক সমতা, যদি পরবর্তী অক্ষরে সমান প্রত্যাবর্তন সত্য এবং পদক্ষেপ কার্সার, আমি নাম ব্যবহার তার জন্য 'স্বীকার করি'।
ভ্যাসিল বোর্স

34

এটি সমাধানের সঠিক উপায় একটি লেক্সার এবং পার্সার সহ । আপনি এগুলির সাধারণ সংস্করণগুলি নিজেরাই লিখতে পারেন, বা সেই পৃষ্ঠাগুলির জাভা লেক্সার এবং পার্সারগুলির লিঙ্ক রয়েছে।

একটি পুনরাবৃত্ত বংশদ্ভুত পার্সার তৈরি করা সত্যিই একটি ভাল শেখার অনুশীলন।


26

আমার বিশ্ববিদ্যালয় প্রকল্পের জন্য, আমি উভয় মৌলিক সূত্র এবং আরও জটিল সমীকরণ (বিশেষত পুনরাবৃত্তি অপারেটর) সমর্থনকারী পার্সার / মূল্যায়নকারী খুঁজছিলাম। আমি জাভা এবং .NET কে এমএক্সপার্সার নামে খুব ভাল ওপেন সোর্স লাইব্রেরি পেয়েছি। সিনট্যাক্স সম্পর্কে কিছুটা অনুভূতি বোধ করার জন্য আমি কয়েকটি উদাহরণ দেব, আরও নির্দেশাবলীর জন্য দয়া করে প্রকল্পের ওয়েবসাইটটি দেখুন (বিশেষত টিউটোরিয়াল বিভাগ)।

https://mathparser.org/

https://mathparser.org/mxparser-tutorial/

https://mathparser.org/api/

এবং কয়েকটি উদাহরণ

1 - সরল ফারমুলা

Expression e = new Expression("( 2 + 3/4 + sin(pi) )/2");
double v = e.calculate()

2 - ব্যবহারকারী সংজ্ঞায়িত যুক্তি এবং ধ্রুবক

Argument x = new Argument("x = 10");
Constant a = new Constant("a = pi^2");
Expression e = new Expression("cos(a*x)", x, a);
double v = e.calculate()

3 - ব্যবহারকারী সংজ্ঞায়িত ফাংশন

Function f = new Function("f(x, y, z) = sin(x) + cos(y*z)");
Expression e = new Expression("f(3,2,5)", f);
double v = e.calculate()

4 - Iteration

Expression e = new Expression("sum( i, 1, 100, sin(i) )");
double v = e.calculate()

সম্প্রতি পাওয়া গেছে - যদি আপনি সিনট্যাক্সটি চেষ্টা করতে চান (এবং উন্নত ব্যবহারের ক্ষেত্রে দেখুন) আপনি এমএক্সপারসার দ্বারা চালিত স্কেলার ক্যালকুলেটর অ্যাপ্লিকেশনটি ডাউনলোড করতে পারেন ।

শুভেচ্ছান্তে


এখন পর্যন্ত এটি সর্বোত্তম গণিত গ্রন্থাগার; কিকস্টার্ট থেকে সহজ, ব্যবহার করা সহজ এবং প্রসারণযোগ্য। অবশ্যই শীর্ষ উত্তর হতে হবে।
ট্রেনকিউইজ মারিউজ

মাভেন সংস্করণটি এখানে সন্ধান করুন
izogfif

আমি দেখেছি এমএক্সপার্সার অবৈধ সূত্র সনাক্ত করতে পারে না, উদাহরণস্বরূপ, '0/0' ফলাফল '0' হিসাবে পাবে। আমি কীভাবে এই সমস্যাটি সমাধান করতে পারি?
লুলিজুন


20

এভেলেক্স নামে গিটহাবের আরও একটি ওপেন সোর্স লাইব্রেরি এখানে

জাভাস্ক্রিপ্ট ইঞ্জিনের বিপরীতে এই পাঠাগারটি শুধুমাত্র গাণিতিক এক্সপ্রেশন মূল্যায়নে মনোনিবেশিত। তদতিরিক্ত, গ্রন্থাগারটি এক্সটেনসিবল এবং বুলিয়ান অপারেটরগুলির পাশাপাশি বন্ধনীগুলির সমর্থন করে।


এটি ঠিক আছে, তবে ব্যর্থ হয় যখন আমরা 5 বা 10 এর গুণকের মানগুলি গুন করার চেষ্টা করি, উদাহরণস্বরূপ 65 * 6 এর ফলাফল 3.9E + 2 ...
পার্থ বাতরা

.কিন্তু
ইন্ট

1
পরিষ্কার করার জন্য, এটি গ্রন্থাগারের সমস্যা নয় বরং ভাসমান পয়েন্টের মান হিসাবে সংখ্যার প্রতিনিধিত্ব করার একটি সমস্যা।
ডেভিডবিটনার

এই গ্রন্থাগারটি সত্যিই ভাল। @ পার্থ বতরা কাস্ট টু ইন্টিমেটেড সকল দশমিক পয়েন্ট সরিয়ে দেবে। পরিবর্তে এটি ব্যবহার করুন: এক্সপ্রেশন.এভাল ()। টু প্লেনস্ট্রিং ();
ein ব্যবহারকারীর

15

আপনি বিনশেল দোভাষী চেষ্টা করতে পারেন :

Interpreter interpreter = new Interpreter();
interpreter.eval("result = (7+21*6)/(32-27)");
System.out.println(interpreter.get("result"));

1
আপনি কী আমাকে অ্যাডনরয়েড স্টুডিওতে বিনশেল ব্যবহার করবেন তা দয়া করে বলতে পারেন।
হ্যানি

1
: - Hanni পোস্টটি আপনি আপনার androidstudio প্রকল্পে বিনশেল যোগ সাহায্য করতে পারে stackoverflow.com/questions/18520875/...
marciowerner

14

যদি আপনার জাভা অ্যাপ্লিকেশনটি ইতিমধ্যে অন্য কোনও জেআর ব্যবহার না করে কোনও ডাটাবেস অ্যাক্সেস করে তবে আপনি সহজেই অভিব্যক্তিগুলির মূল্যায়ন করতে পারেন।

কিছু ডাটাবেসের জন্য আপনাকে একটি ডামি টেবিল ব্যবহার করা প্রয়োজন (যেমন, ওরাকলের "দ্বৈত" টেবিল) এবং অন্যরা আপনাকে কোনও সারণী থেকে "নির্বাচন না করে" এক্সপ্রেশন মূল্যায়নের অনুমতি দেবে।

উদাহরণস্বরূপ, SQL সার্ভার বা স্ক্লাইটে

select (((12.10 +12.0))/ 233.0) amount

এবং ওরাকলে

select (((12.10 +12.0))/ 233.0) amount from dual;

ডিবি ব্যবহারের সুবিধা হ'ল আপনি একই সাথে অনেকগুলি এক্সপ্রেশন মূল্যায়ন করতে পারেন। এছাড়াও বেশিরভাগ ডিবি আপনাকে অত্যন্ত জটিল এক্সপ্রেশন ব্যবহার করতে দেয় এবং এতে অনেকগুলি অতিরিক্ত ক্রিয়াকলাপও থাকে যা প্রয়োজনীয় হিসাবে ডাকা যেতে পারে।

তবে একক একাধিক অভিব্যক্তি স্বতন্ত্রভাবে মূল্যায়নের প্রয়োজন হলে কার্যকারিতা ক্ষতিগ্রস্থ হতে পারে, বিশেষত যখন ডিবি একটি নেটওয়ার্ক সার্ভারে থাকে।

মেমরি ডেটাবেস স্ক্লাইট ব্যবহার করে নিম্নলিখিতটি কিছুটা পারফরম্যান্স সমস্যার সমাধান করে।

জাভাতে এখানে একটি সম্পূর্ণ কাজের উদাহরণ

Class. forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount");
rs.next();
System.out.println(rs.getBigDecimal(1));
stat.close();
conn.close();

অবশ্যই আপনি একই সময়ে একাধিক গণনা পরিচালনা করতে উপরের কোডটি প্রসারিত করতে পারেন।

ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount, (1+100)/20.0 amount2");

5
এসকিউএল ইঞ্জেকশনটিতে হ্যালো বলুন!
সাইবার 19

এটি নির্ভর করে আপনি কীসের জন্য ডিবি ব্যবহার করেন। আপনি যদি নিশ্চিত হতে চান তবে আপনি সহজেই গণিতের মূল্যায়নের জন্য একটি খালি স্ক্লাইট ডিবি তৈরি করতে পারবেন।
ড্যাব 15

4
@cyberz আপনি যদি আমার উপরের উদাহরণটি ব্যবহার করেন তবে স্ক্লাইটটি স্মৃতিতে একটি অস্থায়ী ডিবি তৈরি করবে। দেখুন stackoverflow.com/questions/849679/...
ড্যাব

11

এই নিবন্ধটি বিভিন্ন পন্থা আলোচনা করে। নিবন্ধে উল্লিখিত 2 টি মূল পন্থা এখানে দেওয়া হল:

আপাচে থেকে জেএক্সএল

স্ক্রিপ্টগুলির জন্য জাভা অবজেক্টের রেফারেন্স অন্তর্ভুক্ত করার অনুমতি দেয়।

// Create or retrieve a JexlEngine
JexlEngine jexl = new JexlEngine();
// Create an expression object
String jexlExp = "foo.innerFoo.bar()";
Expression e = jexl.createExpression( jexlExp );

// Create a context and add data
JexlContext jctx = new MapContext();
jctx.set("foo", new Foo() );

// Now evaluate the expression, getting the result
Object o = e.evaluate(jctx);

জেডিকে এম্বেড করা জাভাস্ক্রিপ্ট ইঞ্জিন ব্যবহার করুন:

private static void jsEvalWithVariable()
{
    List<String> namesList = new ArrayList<String>();
    namesList.add("Jill");
    namesList.add("Bob");
    namesList.add("Laureen");
    namesList.add("Ed");

    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");

    jsEngine.put("namesListKey", namesList);
    System.out.println("Executing in script environment...");
    try
    {
      jsEngine.eval("var x;" +
                    "var names = namesListKey.toArray();" +
                    "for(x in names) {" +
                    "  println(names[x]);" +
                    "}" +
                    "namesListKey.add(\"Dana\");");
    }
    catch (ScriptException ex)
    {
        ex.printStackTrace();
    }
}

4
দয়া করে নিবন্ধ থেকে তথ্য সংক্ষিপ্তসার করুন, যদি এর লিঙ্কটি নষ্ট হয়ে যায়।
ডিজেক্লেওয়ার্থ

আমি নিবন্ধটি থেকে প্রাসঙ্গিক বিট অন্তর্ভুক্ত করার জন্য উত্তরটি আপগ্রেড করেছি
ব্র্যাড পার্কস

1
অনুশীলনে, জেএক্সএল ধীরে ধীরে (মটরশুটিগুলির অন্তর্নিদীপনা ব্যবহার করে), মাল্টিথ্রেডিং (গ্লোবাল ক্যাশে) এর সাথে পারফরম্যান্সের সমস্যা রয়েছে
নিশি

@ নিশী জেনে ভাল! - আমার ব্যবহারের ঘটনাটি লাইভ পরিবেশে জিনিসগুলি ডিবাগ করার জন্য ছিল, তবে সাধারণ মোতায়েন করা অ্যাপের অংশ নয় of
ব্র্যাড পার্কস

10

আরেকটি উপায় হ'ল স্প্রিং এক্সপ্রেশন ল্যাঙ্গুয়েজ বা স্পেল ব্যবহার করা যা গাণিতিক অভিব্যক্তিগুলির মূল্যায়নের পাশাপাশি আরও কিছু ঘটে তাই সম্ভবত কিছুটা ওভারকিল। এই এক্সপ্রেশন লাইব্রেরিটি একা একা থাকায় আপনাকে বসন্তের ফ্রেমওয়ার্ক ব্যবহার করতে হবে না। স্পেলের ডকুমেন্টেশন থেকে উদাহরণগুলি অনুলিপি করা হচ্ছে:

ExpressionParser parser = new SpelExpressionParser();
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2 
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); //24.0

এখানে আরও সংক্ষিপ্ত স্পেল উদাহরণ এবং সম্পূর্ণ ডক্স এখানে পড়ুন


8

আমরা যদি এটি প্রয়োগ করতে যাই তবে আমরা নীচের অ্যালগরিদমটি ব্যবহার করতে পারি: -

  1. এখনও পড়ার মতো টোকেন রয়েছে,

    1.1 পরবর্তী টোকেন পান। 1.2 যদি টোকেন হয়:

    1.2.1 একটি সংখ্যা: মান স্ট্যাকের উপর এটি চাপুন push

    ১.২.২ একটি ভেরিয়েবল: এর মানটি পান এবং মান স্ট্যাকের উপরে চাপ দিন।

    1.2.3 একটি বাম বন্ধনী: এটি অপারেটর স্ট্যাকের উপর চাপ দিন।

    1.2.4 একটি ডান প্রথম বন্ধনী:

     1 While the thing on top of the operator stack is not a 
       left parenthesis,
         1 Pop the operator from the operator stack.
         2 Pop the value stack twice, getting two operands.
         3 Apply the operator to the operands, in the correct order.
         4 Push the result onto the value stack.
     2 Pop the left parenthesis from the operator stack, and discard it.

    1.2.5 একটি অপারেটর (এটি কল করুন):

     1 While the operator stack is not empty, and the top thing on the
       operator stack has the same or greater precedence as thisOp,
       1 Pop the operator from the operator stack.
       2 Pop the value stack twice, getting two operands.
       3 Apply the operator to the operands, in the correct order.
       4 Push the result onto the value stack.
     2 Push thisOp onto the operator stack.
  2. অপারেটর স্ট্যাকটি খালি না থাকাকালীন অপারেটর স্ট্যাক থেকে অপারেটরটিকে পপ করুন। 2 দুটি অপারেশন পেয়ে দুবার মান স্ট্যাকটি পপ করুন। 3 অপারেটারগুলিকে সঠিক ক্রমে প্রয়োগ করুন। 4 ফলাফলটি মান স্ট্যাকের উপরে ঠেলাও।

  3. এই মুহুর্তে অপারেটর স্ট্যাকটি খালি থাকতে হবে এবং মান স্ট্যাকের মধ্যে একটি মাত্র মান থাকা উচিত যা চূড়ান্ত ফলাফল।


3
এটি ডিজকস্ট্র শান্টিং-ইয়ার্ড অ্যালগরিদমের একটি অচিহ্নিত প্রদর্শনী । যেখানে দেনা আছে সেখানে দেনা পরিশোধ করুন।
লার্নের মারকুইস



4

আমি মনে করি আপনি কোন উপায়ে এটি করেন এটি প্রচুর শর্তযুক্ত বিবৃতি জড়িত হতে চলেছে। তবে আপনার উদাহরণগুলির মতো একক ক্রিয়াকলাপের জন্য আপনি এটিকে 4 এর মধ্যে সীমাবদ্ধ করতে পারেন যদি কোনও কিছুর সাথে বিবৃতি

String math = "1+4";

if (math.split("+").length == 2) {
    //do calculation
} else if (math.split("-").length == 2) {
    //do calculation
} ...

আপনি যখন "4 + 5 * 6" এর মতো একাধিক ক্রিয়াকলাপ মোকাবেলা করতে চান তখন এটি আরও অনেক জটিল হয়ে যায়।

আপনি যদি কোনও ক্যালকুলেটর তৈরির চেষ্টা করছেন তবে আমি গণনার প্রতিটি বিভাগ একক স্ট্রিংয়ের পরিবর্তে পৃথকভাবে (প্রতিটি সংখ্যা বা অপারেটর) পাস করবো।


2
আপনি একাধিক ক্রিয়াকলাপ, অপারেটর অগ্রাধিকার, প্রথম বন্ধনী, ... সত্যিকারের যে কোনও কিছুই যা আসল পাটিগণিতের প্রকাশকে চিহ্নিত করে তা মোকাবিলা করার সাথে সাথে এটি পুরোপুরি জটিল হয়ে ওঠে। আপনি এই কৌশলটি থেকে শুরু করে সেখানে যেতে পারবেন না।
লার্নের মারকুইস

4

জবাব দিতে দেরি হয়ে গেছে তবে জাভাতে অভিব্যক্তি মূল্যায়ন করতে আমি একই পরিস্থিতি পেরিয়ে এসেছি, এটি কারও সাহায্য করতে পারে

MVELএক্সপ্রেশনগুলির রানটাইম মূল্যায়ন করে না, Stringএটিতে এটি মূল্যায়ন করার জন্য আমরা একটি জাভা কোড লিখতে পারি ।

    String expressionStr = "x+y";
    Map<String, Object> vars = new HashMap<String, Object>();
    vars.put("x", 10);
    vars.put("y", 20);
    ExecutableStatement statement = (ExecutableStatement) MVEL.compileExpression(expressionStr);
    Object result = MVEL.executeExpression(statement, vars);

আমি স্কিওড এবং কিছু অতিরিক্ত পাটিগণিত ফাংশনও পেয়েছি এখানে github.com/mvel/mvel/blob/master/src/test/java/org/mvel2/tests/…
thecode फादर

অসাধারণ সব! এটা আমার দিন বাঁচায়। ধন্যবাদ
সারিকা.এস

4

আপনার সিম্জা ফ্রেমওয়ার্কটি দেখে নিতে পারেন :

ExprEvaluator util = new ExprEvaluator(); 
IExpr result = util.evaluate("10-40");
System.out.println(result.toString()); // -> "-30" 

লক্ষ করুন যে আরও জটিল জটিল এক্সপ্রেশন মূল্যায়ন করা যেতে পারে:

// D(...) gives the derivative of the function Sin(x)*Cos(x)
IAST function = D(Times(Sin(x), Cos(x)), x);
IExpr result = util.evaluate(function);
// print: Cos(x)^2-Sin(x)^2

4

কোড ইঞ্জেকশন হ্যান্ডলিং সহ JDK1.6 এর জাভাস্ক্রিপ্ট ইঞ্জিন ব্যবহার করে নিম্নলিখিত নমুনা কোডটি ব্যবহার করে দেখুন।

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

public class EvalUtil {
private static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
public static void main(String[] args) {
    try {
        System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || 5 >3 "));
        System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || true"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public Object eval(String input) throws Exception{
    try {
        if(input.matches(".*[a-zA-Z;~`#$_{}\\[\\]:\\\\;\"',\\.\\?]+.*")) {
            throw new Exception("Invalid expression : " + input );
        }
        return engine.eval(input);
    } catch (Exception e) {
        e.printStackTrace();
        throw e;
    }
 }
}

4

এটি আসলে @ বোনের দেওয়া উত্তরটির পরিপূরক। এটিতে একটি সামান্য বাগ রয়েছে যা "-2 ^ 2" -4.0 এর ভুল ফলাফল দেয়। তার জন্য সমস্যাটি সেই বিন্দুতে যেখানে তার মধ্যে ক্ষতিকারক মূল্যায়ন করা হয়। পার্সটার্ম () এর ব্লকে ক্ষুদ্রাকর্ষণটি সরান, এবং আপনি ভাল থাকবেন। নীচে দেখুন, যা @ বোয়ানের উত্তরটি সামান্য পরিবর্তিত হয়েছে। পরিবর্তন মন্তব্যে আছে।

public static double eval(final String str) {
    return new Object() {
        int pos = -1, ch;

        void nextChar() {
            ch = (++pos < str.length()) ? str.charAt(pos) : -1;
        }

        boolean eat(int charToEat) {
            while (ch == ' ') nextChar();
            if (ch == charToEat) {
                nextChar();
                return true;
            }
            return false;
        }

        double parse() {
            nextChar();
            double x = parseExpression();
            if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
            return x;
        }

        // Grammar:
        // expression = term | expression `+` term | expression `-` term
        // term = factor | term `*` factor | term `/` factor
        // factor = `+` factor | `-` factor | `(` expression `)`
        //        | number | functionName factor | factor `^` factor

        double parseExpression() {
            double x = parseTerm();
            for (;;) {
                if      (eat('+')) x += parseTerm(); // addition
                else if (eat('-')) x -= parseTerm(); // subtraction
                else return x;
            }
        }

        double parseTerm() {
            double x = parseFactor();
            for (;;) {
                if      (eat('*')) x *= parseFactor(); // multiplication
                else if (eat('/')) x /= parseFactor(); // division
                else if (eat('^')) x = Math.pow(x, parseFactor()); //exponentiation -> Moved in to here. So the problem is fixed
                else return x;
            }
        }

        double parseFactor() {
            if (eat('+')) return parseFactor(); // unary plus
            if (eat('-')) return -parseFactor(); // unary minus

            double x;
            int startPos = this.pos;
            if (eat('(')) { // parentheses
                x = parseExpression();
                eat(')');
            } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
                while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
                x = Double.parseDouble(str.substring(startPos, this.pos));
            } else if (ch >= 'a' && ch <= 'z') { // functions
                while (ch >= 'a' && ch <= 'z') nextChar();
                String func = str.substring(startPos, this.pos);
                x = parseFactor();
                if (func.equals("sqrt")) x = Math.sqrt(x);
                else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
                else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
                else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
                else throw new RuntimeException("Unknown function: " + func);
            } else {
                throw new RuntimeException("Unexpected: " + (char)ch);
            }

            //if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation -> This is causing a bit of problem

            return x;
        }
    }.parse();
}

-2^2 = -4আসলে একটি স্বাভাবিক, এবং একটি বাগ না। এটি গ্রুপবদ্ধ হয়ে যায় -(2^2)উদাহরণস্বরূপ, এটি ডেসমোসে চেষ্টা করুন। আপনার কোডটি আসলে বেশ কয়েকটি বাগ প্রবর্তন করে। প্রথমটি হ'ল ^আর ডান থেকে বামে দলবদ্ধ করে না। অন্য কথায়, 2^3^2গ্রুপ পছন্দ করার কথা মনে করা হয় 2^(3^2)কারণ ^এটি ডান-অ্যাসোসিয়েটিভ, তবে আপনার পরিবর্তনগুলি এটিকে দলটিকে পছন্দ করে (2^3)^2। দ্বিতীয়টি হ'ল এবং এর ^চেয়ে উচ্চতর অগ্রাধিকার রয়েছে বলে মনে করা হয় , তবে আপনার পরিবর্তনগুলি এটির সাথে একই আচরণ করে। আইডিয়োন.আইএনএন 2 এমএমএ দেখুন । */
রেডিওডেফ

সুতরাং, আপনি যা পরামর্শ দিচ্ছেন তা হল যে যেখানে এটি ছিল না সেখানে ক্ষয়ক্ষতি আরও ভালভাবে রাখা হয়?
রোমিও সিয়েরা

হ্যাঁ, আমি এটাই পরামর্শ দিচ্ছি।
রেডিওডেফ

4
package ExpressionCalculator.expressioncalculator;

import java.text.DecimalFormat;
import java.util.Scanner;

public class ExpressionCalculator {

private static String addSpaces(String exp){

    //Add space padding to operands.
    //https://regex101.com/r/sJ9gM7/73
    exp = exp.replaceAll("(?<=[0-9()])[\\/]", " / ");
    exp = exp.replaceAll("(?<=[0-9()])[\\^]", " ^ ");
    exp = exp.replaceAll("(?<=[0-9()])[\\*]", " * ");
    exp = exp.replaceAll("(?<=[0-9()])[+]", " + "); 
    exp = exp.replaceAll("(?<=[0-9()])[-]", " - ");

    //Keep replacing double spaces with single spaces until your string is properly formatted
    /*while(exp.indexOf("  ") != -1){
        exp = exp.replace("  ", " ");
     }*/
    exp = exp.replaceAll(" {2,}", " ");

       return exp;
}

public static Double evaluate(String expr){

    DecimalFormat df = new DecimalFormat("#.####");

    //Format the expression properly before performing operations
    String expression = addSpaces(expr);

    try {
        //We will evaluate using rule BDMAS, i.e. brackets, division, power, multiplication, addition and
        //subtraction will be processed in following order
        int indexClose = expression.indexOf(")");
        int indexOpen = -1;
        if (indexClose != -1) {
            String substring = expression.substring(0, indexClose);
            indexOpen = substring.lastIndexOf("(");
            substring = substring.substring(indexOpen + 1).trim();
            if(indexOpen != -1 && indexClose != -1) {
                Double result = evaluate(substring);
                expression = expression.substring(0, indexOpen).trim() + " " + result + " " + expression.substring(indexClose + 1).trim();
                return evaluate(expression.trim());
            }
        }

        String operation = "";
        if(expression.indexOf(" / ") != -1){
            operation = "/";
        }else if(expression.indexOf(" ^ ") != -1){
            operation = "^";
        } else if(expression.indexOf(" * ") != -1){
            operation = "*";
        } else if(expression.indexOf(" + ") != -1){
            operation = "+";
        } else if(expression.indexOf(" - ") != -1){ //Avoid negative numbers
            operation = "-";
        } else{
            return Double.parseDouble(expression);
        }

        int index = expression.indexOf(operation);
        if(index != -1){
            indexOpen = expression.lastIndexOf(" ", index - 2);
            indexOpen = (indexOpen == -1)?0:indexOpen;
            indexClose = expression.indexOf(" ", index + 2);
            indexClose = (indexClose == -1)?expression.length():indexClose;
            if(indexOpen != -1 && indexClose != -1) {
                Double lhs = Double.parseDouble(expression.substring(indexOpen, index));
                Double rhs = Double.parseDouble(expression.substring(index + 2, indexClose));
                Double result = null;
                switch (operation){
                    case "/":
                        //Prevent divide by 0 exception.
                        if(rhs == 0){
                            return null;
                        }
                        result = lhs / rhs;
                        break;
                    case "^":
                        result = Math.pow(lhs, rhs);
                        break;
                    case "*":
                        result = lhs * rhs;
                        break;
                    case "-":
                        result = lhs - rhs;
                        break;
                    case "+":
                        result = lhs + rhs;
                        break;
                    default:
                        break;
                }
                if(indexClose == expression.length()){
                    expression = expression.substring(0, indexOpen) + " " + result + " " + expression.substring(indexClose);
                }else{
                    expression = expression.substring(0, indexOpen) + " " + result + " " + expression.substring(indexClose + 1);
                }
                return Double.valueOf(df.format(evaluate(expression.trim())));
            }
        }
    }catch(Exception exp){
        exp.printStackTrace();
    }
    return 0.0;
}

public static void main(String args[]){

    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter an Mathematical Expression to Evaluate: ");
    String input = scanner.nextLine();
    System.out.println(evaluate(input));
}

}


1
অপারেটর অগ্রাধিকার, বা বেশ কয়েকটি অপারেটর, বা প্রথম বন্ধনী পরিচালনা করে না। ব্যবহার করবেন না.
লার্নের মারকুইস

2

কিভাবে ভালো কিছু সম্পর্কে:

String st = "10+3";
int result;
for(int i=0;i<st.length();i++)
{
  if(st.charAt(i)=='+')
  {
    result=Integer.parseInt(st.substring(0, i))+Integer.parseInt(st.substring(i+1, st.length()));
    System.out.print(result);
  }         
}

এবং সেই সাথে প্রতিটি অন্যান্য গাণিতিক অপারেটরের জন্য একই কাজ করুন ..


9
আপনার দক্ষ গণিতের এক্সপ্রেশন পার্সার লেখার বিষয়ে পড়া উচিত। এটিতে একটি কম্পিউটার বিজ্ঞান পদ্ধতি রয়েছে। উদাহরণস্বরূপ, এএনটিএলআর একবার দেখুন। আপনি যা লিখেছেন সে সম্পর্কে আপনি যদি ভালভাবে চিন্তা করেন তবে আপনি দেখতে পাবেন যে (এ + বি / -সি) * (ই / এফ) এর মতো জিনিসগুলি আপনার ধারণার সাথে কাজ করবে না বা কোডটি সুপার ডুপার নোংরা এবং অকার্যকর হবে।
ড্যানিয়েল নুরিয়েভ

2
এটি একটি সুইচ কেস স্টেটমেন্টের চেয়ে খারাপ ...
প্রোগ্রামারস 5

2

জিক্স্র্টর শান্টিং-ইয়ার্ড অ্যালগরিদম ব্যবহার করে ইনফিক্স সংকেতটিতে যে কোনও এক্সপ্রেশন স্ট্রিং পোস্টফিক্স স্বরলিপিতে রূপান্তর করা সম্ভব । অ্যালগরিদমের ফলাফল তার পরে পোস্টফিক্স অ্যালগরিদমের ইনপুট হিসাবে পরিবেশন করতে পারে সাথে প্রকাশের ফলাফল দেয়।

আমি জাভা প্রয়োগের সাথে এখানে এটি সম্পর্কে একটি নিবন্ধ লিখেছিলাম


2

তবুও অন্য বিকল্প: https://github.com/stefanhaustein/expressionparser

আমি উভয়কেই অনুমতি দেওয়ার জন্য একটি সহজ তবে নমনীয় বিকল্প রাখতে এটি প্রয়োগ করেছি:

উপরে লিখিত TreeBuilder একটি অংশ সিএএস ডেমো প্যাকেজের যা প্রতীকী ডেরাইভেশন করে। এখানে একটা হল বেসিক ইন্টারপ্রেটার উদাহরণ এবং আমি একটি নির্মাণ করতে শুরু করেছে অনুবাদক টাইপ করা বিষয় এটি ব্যবহার।


2

একটি জাভা ক্লাস যা গাণিতিক এক্সপ্রেশন মূল্যায়ন করতে পারে:

package test;

public class Calculator {

    public static Double calculate(String expression){
        if (expression == null || expression.length() == 0) {
            return null;
        }
        return calc(expression.replace(" ", ""));
    }
    public static Double calc(String expression) {

        if (expression.startsWith("(") && expression.endsWith(")")) {
            return calc(expression.substring(1, expression.length() - 1));
        }
        String[] containerArr = new String[]{expression};
        double leftVal = getNextOperand(containerArr);
        expression = containerArr[0];
        if (expression.length() == 0) {
            return leftVal;
        }
        char operator = expression.charAt(0);
        expression = expression.substring(1);

        while (operator == '*' || operator == '/') {
            containerArr[0] = expression;
            double rightVal = getNextOperand(containerArr);
            expression = containerArr[0];
            if (operator == '*') {
                leftVal = leftVal * rightVal;
            } else {
                leftVal = leftVal / rightVal;
            }
            if (expression.length() > 0) {
                operator = expression.charAt(0);
                expression = expression.substring(1);
            } else {
                return leftVal;
            }
        }
        if (operator == '+') {
            return leftVal + calc(expression);
        } else {
            return leftVal - calc(expression);
        }

    }

    private static double getNextOperand(String[] exp){
        double res;
        if (exp[0].startsWith("(")) {
            int open = 1;
            int i = 1;
            while (open != 0) {
                if (exp[0].charAt(i) == '(') {
                    open++;
                } else if (exp[0].charAt(i) == ')') {
                    open--;
                }
                i++;
            }
            res = calc(exp[0].substring(1, i - 1));
            exp[0] = exp[0].substring(i);
        } else {
            int i = 1;
            if (exp[0].charAt(0) == '-') {
                i++;
            }
            while (exp[0].length() > i && isNumber((int) exp[0].charAt(i))) {
                i++;
            }
            res = Double.parseDouble(exp[0].substring(0, i));
            exp[0] = exp[0].substring(i);
        }
        return res;
    }


    private static boolean isNumber(int c) {
        int zero = (int) '0';
        int nine = (int) '9';
        return (c >= zero && c <= nine) || c =='.';
    }

    public static void main(String[] args) {
        System.out.println(calculate("(((( -6 )))) * 9 * -1"));
        System.out.println(calc("(-5.2+-5*-5*((5/4+2)))"));

    }

}

2
অপারেটর অগ্রাধিকার সঠিকভাবে পরিচালনা করে না। এটি করার স্ট্যান্ডার্ড উপায় রয়েছে এবং এটি তাদের মধ্যে একটিও নয়।
লর্নে

ইজেপি, আপনি দয়া করে বলতে পারেন যেখানে অপারেটর অগ্রাধিকার নিয়ে কোনও সমস্যা আছে? আমি এটির সাথে পুরোপুরি একমত যে এটি করার মানক উপায় নয়। পূর্ববর্তী পোস্টগুলিতে ইতিমধ্যে স্ট্যান্ডার্ড উপায়গুলি উল্লেখ করা হয়েছিল, ধারণাটি হ'ল এটি করার অন্য কোনও উপায় দেখানো।
এফি জি

2

জাভাস্ক্রিপ্ট চালানোর জন্য RHINO বা NASHORN এর মতো বাহ্যিক লাইব্রেরি ব্যবহার করা যেতে পারে। এবং জাভাস্ক্রিপ্ট স্ট্রিংটি পার্সিং না করে সহজ সূত্রটি মূল্যায়ন করতে পারে। কোডটি ভালভাবে লেখা থাকলে কোনও পারফরম্যান্স প্রভাব নেই। নীচে RHINO এর সাথে একটি উদাহরণ দেওয়া হল -

public class RhinoApp {
    private String simpleAdd = "(12+13+2-2)*2+(12+13+2-2)*2";

public void runJavaScript() {
    Context jsCx = Context.enter();
    Context.getCurrentContext().setOptimizationLevel(-1);
    ScriptableObject scope = jsCx.initStandardObjects();
    Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
    Context.exit();
    System.out.println(result);
}

2
import java.util.*;

public class check { 
   int ans;
   String str="7 + 5";
   StringTokenizer st=new StringTokenizer(str);

   int v1=Integer.parseInt(st.nextToken());
   String op=st.nextToken();
   int v2=Integer.parseInt(st.nextToken());

   if(op.equals("+")) { ans= v1 + v2; }
   if(op.equals("-")) { ans= v1 - v2; }
   //.........
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.