كيفية تحليل تعبير رياضي معطى كسلسلة وإرجاع رقم؟[ينسخ]

StackOverflow https://stackoverflow.com/questions/1432245

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

هل هناك طريقة في Java للحصول على النتيجة من هذا التعبير الرياضي:

String code = "5+4*(7-15)";

ومن ناحية أخرى ما هي أفضل طريقة لتحليل التعبير الحسابي؟

هل كانت مفيدة؟

المحلول

يمكنك تمريرها إلى أ بينشيل bsh.Interpreter, ، شيء من هذا القبيل:

Interpreter interpreter = new Interpreter();
interpreter.eval("result = 5+4*(7-15)");
System.out.println(interpreter.get("result"));

ستحتاج إلى التأكد من أن السلسلة التي تقوم بتقييمها هي من مصدر موثوق به والاحتياطات المعتادة ولكن بخلاف ذلك ستعمل بشكل مستقيم.

إذا كنت تريد اتباع نهج أكثر تعقيدًا (ولكنه أكثر أمانًا) فيمكنك استخدامه أنتلر (الذي أظن أنه يحتوي على قواعد نحوية رياضية كنقطة بداية) وقم بالفعل بتجميع/تفسير البيان بنفسك.

نصائح أخرى

لقد قمت مؤخرًا بتطوير محلل تعبيري وأصدرته بموجب ترخيص Apache.يمكنك الاستيلاء عليها في http://projects.congrace.de/exp4j/index.html

نأمل أن ساعد

يمكنك استخدام فئة ScriptEngine وتقييمها كسلسلة جافا سكريبت

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");        
Object result = engine.eval("5+4*(7-15)");

في الواقع، يجب أن تعلم أن نتيجة التعليمات التالية في جافا سكريبت:

   eval('var aa=5+4*(7-15)')
   aa // -27

قد تكون هناك طريقة أفضل، ولكن هذه الطريقة تعمل.

ربما ليس بطريقة مباشرة كما كنت تأمل!

ولكن ربما يمكنك استخدام javax.script.ScriptEngine والتعامل مع السلسلة كتعبير ECMAScript، على سبيل المثال؟

ألق نظرة على: البرمجة النصية لمنصة جافا.

لا توجد طريقة مدمجة للقيام بذلك.ولكن يمكنك استخدام واحدة من العديد منها الآلات الحاسبة مفتوحة المصدر متاح.

كنت مؤخرًا أستخدم مكتبة محلل التعبيرات الرياضية الناضجة جدًا، مفتوحة المصدر، وتوفر نفس واجهة برمجة التطبيقات لـ JAVA و.NET.اسم المكتبة هو mXparser.يوفر mXparser وظائف أساسية (تحليل وحساب الصيغ البسيطة) ووظائف أكثر تقدمًا (على سبيل المثال.الوسائط والوظائف التي يحددها المستخدم).بالإضافة إلى ذلك، تجدر الإشارة إلى أن mXparser يحتوي على مجموعة رياضية غنية مدمجة (أي عوامل التشغيل، والوظائف الأحادية/الثنائية/المتغيرة، والعوامل المتكررة مثل الجمع والمنتج).

http://mathparser.org/

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

يرجى الاطلاع أدناه على بعض الأمثلة للحصول على رؤية أكثر وضوحًا حول بناء الجملة.

المثال 1 - صيغة بسيطة

Expression e = new Expression("2+3");
double v = e.calculate();

مثال 2 - وظيفة مدمجة

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

مثال 3 - الثوابت المضمنة

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

المثال 4 - الحجج والثوابت التي يحددها المستخدم

Argument x = new Argument("x = 5");
Constant a = new Constant("a = 2 + sin(3)");
Expression e = new Expression("a + x^2", x, a);
double v1 = e.calculate();
x.setArgumentValue(10);
double v2 = e.calculate();

المثال 5 - الوظائف المحددة من قبل المستخدم

Function f = new Function("f(x,y) = x^2 + cos(y)");
Expression e = new Expression("f(10,pi) - 3", f);
double v = e.calculate();

المثال 6 - التكرار المحدد من قبل المستخدم

Function factorial = new Function("fact(n) = if( n > 0; n*fact(n-1); 1)");
Expression e = new Expression("fact(10) - 10!", factorial);
double v = e.calculate();

تم العثور عليه مؤخرًا - في حالة رغبتك في تجربة بناء الجملة (ورؤية حالة الاستخدام المتقدمة) يمكنك تنزيل الملف حاسبة العددية التطبيق المدعوم من mXparser.

أطيب التحيات

إل كيه

لا يوجد دعم مباشر في Java SDK للقيام بذلك.

سيتعين عليك إما تنفيذ ذلك بنفسك (ربما باستخدام مولد محلل مثل JavaCC)، أو استخدام مكتبة موجودة.

سيكون أحد الخيارات جيب (تجاري)، آخر جيفال (برمجيات مجانية).

هناك أداة تجارية تسمى صيغة4j الذي يقوم بهذه المهمة.

لأخذ التعبير كمثال، سيتم تقييمه على النحو التالي باستخدام الصيغة 4j:

Formula formula = new Formula("5+4*(7-15)");

Decimal answer = formula.getAnswer(); //-27

يمكنك استخدام ذلك مشروع

كيف تستعمل:

double result = 0;
String code = "5+4*(7-15)";
try {
    Expr expr = Parser.parse(code);
    result = expr.value();
} catch (SyntaxException e) {
    e.printStackTrace();
}
System.out.println(String.format("Result: %.04f", result));
public static int calc(String string){
    int result=0; 
    String numbers="0123456789";
    String operations="+-/*";
    for (int i=0;i<string.length();i++){
        if (numbers.contains(string.charAt(i)+"")){
            result=result*10+(Integer.parseInt(string.charAt(i)+""));
            }
        else {
            if (string.charAt(i)=='+'){ result+=calc(string.substring(i+1));}
            if (string.charAt(i)=='-'){ result-=calc(string.substring(i+1));}
            if (string.charAt(i)=='*'){ result*=calc(string.substring(i+1));}
            if (string.charAt(i)=='/'){ try{result/=calc(string.substring(i+1));}
                catch (ArithmeticException e){
                    System.err.println("You cannot devide by Zero!");}
            }  
            break;
        }        
    }
    return result;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top