क्या .NET में एक स्ट्रिंग गणित मूल्यांकनकर्ता है?


95

अगर मेरे पास एक मान्य गणित अभिव्यक्ति के साथ एक स्ट्रिंग है जैसे:

String s = "1 + 2 * 7";

क्या .NET / लाइब्रेरी में एक ऐसा फ़ंक्शन है जो .NET में बनेगा और मेरे लिए उस एक्सप्रेशन का मूल्यांकन करेगा और परिणाम देगा? इस मामले में 15।


2
एक में नहीं बनी। लेकिन यहाँ एक बहुत व्यापक है
स्ट्रालोक


1
आप अभिव्यक्ति मूल्यांकनकर्ता (100% प्रबंधित .NET में Eval फ़ंक्शन) का उपयोग कर सकते हैं
jadsc

मैंने C # में गणितीय अभिव्यक्तियों का मूल्यांकन करने के लिए केवल एक कोड-केवल समाधान बनाया। आप कोड को blackbeltcoder.com/Articles/algorithms/ac-expression-evaluator पर देख सकते हैं ।
जोनाथन वुड

इस लाइब्रेरी में कुछ कीड़े हैं।
फिलिप लावोई

जवाबों:


53

आप Microsoft स्क्रिप्ट कंट्रोल लाइब्रेरी (COM) का संदर्भ जोड़ सकते हैं और एक अभिव्यक्ति का मूल्यांकन करने के लिए इस तरह कोड का उपयोग कर सकते हैं। (JScript के लिए भी काम करता है।)

Dim sc As New MSScriptControl.ScriptControl()
sc.Language = "VBScript"
Dim expression As String = "1 + 2 * 7"
Dim result As Double = sc.Eval(expression)

संपादित करें - C # संस्करण।

MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl();
sc.Language = "VBScript";
string expression = "1 + 2 * 7";
object result = sc.Eval(expression);            
MessageBox.Show(result.ToString());

संपादित करें - ScriptControl एक COM ऑब्जेक्ट है। प्रोजेक्ट के "संदर्भ जोड़ें" संवाद में "COM" टैब चुनें और "Microsoft स्क्रिप्ट नियंत्रण 1.0" पर स्क्रॉल करें और ठीक चुनें।


2
यद्यपि यह उत्तर के रूप में चिह्नित है, यह 10 साल पहले था और COM अब मृत की तरह है। मैं नीचे DataTable.Compute उत्तर पसंद करता हूं।
dwilliss

64

अजीब बात है कि इस प्रसिद्ध और पुराने सवाल का कोई जवाब नहीं है जो बिलिन का सुझाव देता है DataTable.Compute- "चाल"। यही पर है।

double result = Convert.ToDouble(new DataTable().Compute("1 + 2 * 7", null));

निम्नलिखित अंकगणितीय संचालकों को अभिव्यक्तियों में समर्थन दिया जाता है:

+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulus)

अधिक जानकारियां: DataColumn.Expressionपर अभिव्यक्ति सिंटेक्स


वहाँ 15 नवंबर को ma81xx से एक जवाब था '11
tatigo

1
आप सही हैं, लेकिन वह गणना पद्धति का उपयोग नहीं कर रहा था।
टिम श्मेल्टर

आपका उदाहरण मुझे देता है। System.InvalidCastException उपयोगकर्ता कोड HResult = -2147467262 द्वारा अनहैंड कर दिया गया था, मैं इसे कैसे ठीक कर सकता हूं?
यूलिया एशोमोक

यह मेरे लिए काम करता है, क्या आपने इस नमूना कोड का उपयोग किया है? डिबगर का उपयोग करें और परिणाम मान का निरीक्षण करें, प्रकार का उल्लेख किया गया है।
टिम शिल्टर

28

सिल्वरलाइट पर C # में किसी को भी विकसित करने के लिए यहाँ एक बहुत साफ चाल है जिसे मैंने अभी-अभी खोजा है जो जावास्क्रिप्ट इंजन को कॉल करके अभिव्यक्ति के मूल्यांकन की अनुमति देता है:

double result = (double) HtmlPage.Window.Eval("15 + 35");

मुझे आश्चर्य है कि क्या आप इसे कहीं और संदर्भित कर सकते हैं। शायद नहीं, लेकिन यह अच्छा होगा।
जोएल कोएहॉर्न

4
जैसा कि यह मनमाने ढंग से जावास्क्रिप्ट कोड का मूल्यांकन करता है, आप शायद अपने इनपुट को साफ करना सुनिश्चित करें और सुनिश्चित करें कि आप सीधे परिणाम प्रदर्शित नहीं कर रहे हैं। (मुझे लगता है कि यह एक्सएसएस को साकार करने के बिना इसे पेश करने का एक अच्छा तरीका होगा)
दान एस्पराजा

एक अग्रणी शून्य के साथ संख्या दर्ज करने का प्रयास करें, परिणाम विश्वसनीय नहीं है। "054 + 6" आपको उदाहरण के लिए 50 देता है।
टेरी

9
@ डेजेरी, क्योंकि एक प्रमुख शून्य के साथ संख्याओं को जेएस के मूल्यांकनकर्ता द्वारा अष्टक माना जाता है, और ऑक्टल 054 दशमलव 44 के बराबर होता है।
एंड्रे लेरिया

24

क्या आपने http://ncalc.codeplex.com देखा है ?

यह एक्स्टेंसिबल है, तेज़ (जैसे कि इसका अपना कैश है) आपको मूल्यांकन / मूल्यांकन मूल्यांकन घटनाओं को संचालित करके कस्टम कार्यों और चलाने के समय पर varaibles प्रदान करने में सक्षम बनाता है। उदाहरण अभिव्यक्ति यह पार्स कर सकती है:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)"); 

  e.Parameters["Pi2"] = new Expression("Pi * Pi"); 
  e.Parameters["X"] = 10; 

  e.EvaluateParameter += delegate(string name, ParameterArgs args) 
    { 
      if (name == "Pi") 
      args.Result = 3.14; 
    }; 

  Debug.Assert(117.07 == e.Evaluate()); 

यह यूनिकोड और कई डेटा प्रकार को मूल रूप से भी संभालता है। यदि आप ग्रामर बदलना चाहते हैं तो यह एक एंटलर फाइल के साथ आता है। एक कांटा भी है जो नए कार्यों को लोड करने के लिए MEF का समर्थन करता है।


1
महान पुस्तकालय। NUGET पर भी उपलब्ध है
पॉल

यह वही है जो मैंने अपने अंतर समीकरण सॉल्वर के लिए उपयोग किया था जो उपयोगकर्ता के इनपुट के लिए लिया था। प्रश्न यहाँ है
kleineg

15

वास्तव में एक तरह से बनाया गया है - आप XPath नाम स्थान का उपयोग कर सकते हैं! हालांकि यह आवश्यक है कि आप XPath अंकन के साथ पुष्टि करने के लिए स्ट्रिंग को पुन: स्वरूपित करें। मैंने सरल अभिव्यक्ति को संभालने के लिए इस तरह की विधि का उपयोग किया है:

    public static double Evaluate(string expression)
    {
        var xsltExpression = 
            string.Format("number({0})", 
                new Regex(@"([\+\-\*])").Replace(expression, " ${1} ")
                                        .Replace("/", " div ")
                                        .Replace("%", " mod "));

        return (double)new XPathDocument
            (new StringReader("<r/>"))
                .CreateNavigator()
                .Evaluate(xsltExpression);
    }

12

प्रारंभ में मैंने muparser के लिए c # आवरण का उपयोग किया । यह बहुत तेज था। एकमात्र तेज़ समाधान मुझे पता है कि एक्सपर्ट है । यदि आप अन्य समाधानों की तलाश कर रहे हैं तो आप बेंचमार्क चेकआउट कर सकते हैं ।

लेकिन .Net के मामले में आप रनटाइम पर कोड संकलित करने के लिए बिलिन सपोर्ट का उपयोग कर सकते हैं। विचार के लिए एक "टेम्पलेट" स्रोत फ़ाइल है जैसे कि एम्बेडेड संसाधन जहां आप मूल्यांकन के लिए सूत्र को बदल सकते हैं। फिर आप इस तैयार वर्ग-स्रोत-कोड को संकलक को पास करते हैं।

एक बुनियादी टेम्पलेट इस तरह दिख सकता है:

public class CSCodeEvaler
{
    public double EvalCode()
    {
        return last = Convert.ToDouble(%formula%);
    }

    public double last = 0;
    public const double pi = Math.PI;
    public const double e = Math.E;
    public double sin(double value) { return Math.Sin(value); }
    public double cos(double value) { return Math.Cos(value); }
    public double tan(double value) { return Math.Tan(value); }
    ...

उस% सूत्र% को ध्यान दें जहाँ अभिव्यक्ति को रखा जाएगा।

CSharpCodeProvider वर्ग का उपयोग करने के लिए। मैं यहां पूर्ण स्रोत में नहीं डालना चाहता हूं। लेकिन यह जवाब मदद कर सकता है:

आपके पास मेमोरी असेंबली लोड होने के बाद आप अपनी कक्षा का एक उदाहरण बना सकते हैं और EvalCode को कॉल कर सकते हैं।


9

अभी तक एक और विकल्प है कि रोसलिन उपलब्ध है:

इसके लिए आप CodeAnalysis.CSharp.Scripting लाइब्रेरी का उपयोग कर सकते हैं।

using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;

namespace ExpressionParser
{
    class Program
    {
        static void Main(string[] args)
        {
            //Demonstrate evaluating C# code
            var result = CSharpScript.EvaluateAsync("System.DateTime.Now.AddDays(-1) > System.DateTime.Now").Result;
            Console.WriteLine(result.ToString());

            //Demonstrate evaluating simple expressions
            var result2 = CSharpScript.EvaluateAsync(" 5 * 7").Result;
            Console.WriteLine(result2);
            Console.ReadKey();
        }
    }
}

नगेट पैकेज:

<package id="Microsoft.CodeAnalysis.Analyzers" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Common" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.CSharp" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.CSharp.Scripting" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Scripting" version="1.1.1" targetFramework="net461" />
<package id="Microsoft.CodeAnalysis.Scripting.Common" version="1.1.1" targetFramework="net461" />

2
इसका उत्तर अभी होना चाहिए
सोनोफ़ाफॉस्टर

8

हाल ही में मैं mXparser का उपयोग कर रहा था, जो .NET और JAVA के लिए एक गणित पार्सर लाइब्रेरी है। mXparser बुनियादी फ़ार्मुलों के साथ-साथ बहुत फैंसी / जटिल लोगों (चर, कार्यों, ऑपरेटरों, पुनरावृत्ति और पुनरावृत्ति सहित) का समर्थन करता है।

https://mxparser.codeplex.com/

https://mathparser.org/

कुछ उपयोग उदाहरण:

उदाहरण 1:

Expression e = new Expression("1+2*7 + (sin(10) - 2)/3");
double v = e.calculate();

उदाहरण 2:

Argument x = new Argument("x = 5");
Expression e = new Expression("2*x+3", x);
double v = e.calculate();

उदाहरण 3:

Function f = new Function("f(x,y) = sin(x) / cos(y)");
Expression e = new Expression("f(pi, 2*pi) - 2", f);
double v = e.calculate();

हाल ही में मिला - यदि आप वाक्यविन्यास को आज़माना चाहते हैं (और उन्नत उपयोग के मामले को देखें) तो आप स्केलर कैलकुलेटर ऐप डाउनलोड कर सकते हैं जो mXparser द्वारा संचालित है।

सादर


यह मुझे मिली सबसे अच्छी लाइब्रेरी है। हालाँकि, यह संख्या के अलावा किसी भी डेटा प्रकार का समर्थन नहीं करता है! मुझे डेटटाइम और स्ट्रिंग की आवश्यकता है .. क्या आप कोई अच्छा विकल्प जानते हैं?
होमम

@ होम्म क्या आपको स्ट्रिंग ऑपरेशन के लिए एक विकल्प मिला
रामकृष्ण रेड्डी

5

यदि आपको बहुत ही सरल चीज़ की आवश्यकता है तो आप DataTable:-) का उपयोग कर सकते हैं

Dim dt As New DataTable
dt.Columns.Add("A", GetType(Integer))
dt.Columns.Add("B", GetType(Integer))
dt.Columns.Add("C", GetType(Integer))
dt.Rows.Add(New Object() {12, 13, DBNull.Value})

Dim boolResult As Boolean = dt.Select("A>B-2").Length > 0

dt.Columns.Add("result", GetType(Integer), "A+B*2+ISNULL(C,0)")
Dim valResult As Object = dt.Rows(0)("result")

3

मैं Jace ( https://github.com/pieterderycke/Jace ) पर भी नज़र डालूंगा । Jace एक उच्च प्रदर्शन गणित पार्सर और गणना इंजन है जो सभी .NET फ्लेवर (.NET 4.x, विंडोज फोन, विंडोज स्टोर, ...) का समर्थन करता है। Jace NuGet: https://www.nuget.org/packages/Jace के माध्यम से भी उपलब्ध है


3

एक साधारण गणित पार्सर बनाने में काफी आसान है, और इसके लिए केवल कुछ लाइनों की आवश्यकता होती है:

इस लचीले उदाहरण को लें:

class RPN
{
    public static double Parse( Stack<string> strStk )
    {
        if (strStk == null || strStk.Count == 0 )
        {
            return 0;
        }
        Stack<double> numStk = new Stack<double>();
        double result = 0;

        Func<double, double> op = null;
        while (strStk.Count > 0)
        {
            var s = strStk.Pop();
            switch (s)
            {
                case "+":
                    op = ( b ) => { return numStk.Pop() + b; };
                    break;
                case "-":
                    op = ( b ) => { return numStk.Pop() - b; };
                    break;
                case "*":
                    op = ( b ) => { return numStk.Pop() * b; };
                    break;
                case "/":
                    op = ( b ) => { return numStk.Pop() / b; };
                    break;

                default:
                    double.TryParse(s, NumberStyles.Any, out result);
                    if (numStk.Count > 0)
                    {
                        result = op(result);
                    }
                    numStk.Push(result);
                    break;
            }
        }
        return result;
    }
}

....
var str = " 100.5 + 300.5 - 100 * 10 / 100";    
str = Regex.Replace(str, @"\s", "", RegexOptions.Multiline);
Stack<string> strStk = new Stack<string>(
     Regex.Split(str, @"([()*+\/-])", RegexOptions.Multiline).Reverse()
);
RPN.Parse(strStk);

पूर्ववर्ती स्थिति को सक्षम करने के लिए ढेर के ढेर को फिर से लगाना होगा, जैसे कि पुनरावृत्ति द्वारा संग्रहीत। कोष्ठक के बीच कुछ भी एक नए ढेर पर रखा जाता है। अंत में आप लैम्ब्डा द्वारा एक साफ पठनीय फैशन में गणित के संचालन का समर्थन कर सकते हैं।


आप अपने उत्तर को सत्यापित करना चाह सकते हैं। 100.5 + 300.5 - 100 * 10 / 100 = 30.1बनाम391
तवानी

1
namespace CalcExp
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            double res = Evaluate("4+5/2-1");

            Console.WriteLine(res);

        }

        public static double Evaluate(string expression)
        {
            var xsltExpression =
                string.Format("number({0})",
                    new Regex(@"([\+\-\*])").Replace(expression, " ${1} ")
                                            .Replace("/", " div ")
                                            .Replace("%", " mod "));

// ReSharper disable PossibleNullReferenceException
            return (double)new XPathDocument
                (new StringReader("<r/>"))
                    .CreateNavigator()
                    .Evaluate(xsltExpression);
// ReSharper restore PossibleNullReferenceException
        }

    }
}

3
-1: बस इसे @cbp उत्तर में मर्ज करें। ज़ीरो के दो उत्तर होने की आवश्यकता है जो मौलिक रूप से समान हैं जब हमारे पास एक शानदार उत्तर हो सकता है।
रॉबर्ट मैकलीन

1

मैंने कुछ साल पहले एक अभिव्यक्ति पार्सर लागू किया था और हाल ही में GitHub और Nuget: Albatross.Expression में इसका एक संस्करण प्रकाशित किया था । इसमें एक एक्ज़ेक्यूशन कोटेक्स्ट क्लास शामिल है जो कि अभिव्यक्ति के एक सेट का मूल्यांकन कर सकता है जैसे:

  • एमवी = मूल्य * मात्रा;
  • मूल्य = (बोली + पूछ) / 2;
  • बोली = 6;
  • पूछ = = 8;

यह परिपत्र संदर्भ जांच में भी बनाया गया है जो स्टैक ओवरफ्लो से बचने के लिए उपयोगी है।


1

आप मैथ-एक्सप्रेशन-इवैल्यूएटर लाइब्रेरी का उपयोग कर सकते हैं जो मैं लेखक हूं। यह सरल भाव का समर्थन करता है जैसे 2.5+5.9, 17.89-2.47+7.16, 5/2/2+1.5*3+4.58, कोष्ठकों के साथ भाव (((9-6/2)*2-4)/2-6-1)/(2+24/(2+4))और चर के साथ भाव:

var a = 6;
var b = 4.32m;
var c = 24.15m;
var engine = new ExpressionEvaluator();
engine.Evaluate("(((9-a/2)*2-b)/2-a-1)/(2+c/(2+4))", new { a, b, c});

आप नामित चर के रूप में पैरामीटर भी पास कर सकते हैं:

dynamic dynamicEngine = new ExpressionEvaluator();

var a = 6;
var b = 4.5m;
var c = 2.6m;

dynamicEngine.Evaluate("(c+b)*a", a: 6, b: 4.5, c: 2.6);

यह .Net Standard 2.0 को सपोर्ट करता है। इसका इस्तेमाल .NET नेट के साथ-साथ .Net फुल फ्रेमवर्क प्रोजेक्ट्स से भी किया जा सकता है और इसमें कोई बाहरी निर्भरता नहीं है।


0

फ्ली फास्ट लाइटवेट एक्सप्रेशन इवैल्यूएटर

https://flee.codeplex.com

भाषा संदर्भ

  • ArithmeticOperators उदाहरण: एक * 2 + b ^ 2 - 100% 5
  • तुलना करने वाले उदाहरण: एक <> 100
  • AndOrXorNotOperators उदाहरण (तार्किक): ए> 100 और बी = 100 नहीं
  • ShiftOperators उदाहरण: 100 >> 2
  • संबंध उदाहरण: "abc" + "def"
  • अनुक्रमण उदाहरण: गिरफ्तारी [i + 1] + 100
  • शाब्दिक
  • कास्टिंग उदाहरण: 100 + कास्ट (obj, int)
  • ConditionalOperator उदाहरण: यदि (a> 100 और b> 10, "दोनों अधिक", "कम")
  • InOperator उदाहरण (सूची): यदि (100 में (100, 200, 300, -1), "in," in "नहीं")
  • ओवरलोडेड ऑपरेटर्स ऑन टाइप्स

उदाहरण :

Imports Ciloci.Flee
Imports Ciloci.Flee.CalcEngine
Imports System.Math

    Dim ec As New Ciloci.Flee.ExpressionContext
    Dim ex As IDynamicExpression
    ec.Imports.AddType(GetType(Math))

    ec.Variables("a") = 10            
    ec.Variables("b") = 40               
    ex = ec.CompileDynamic("a+b")

    Dim evalData    
    evalData = ex.Evaluate()
    Console.WriteLine(evalData)

आउटपुट: 50


0

MathNet.Symbolics

using System;
using static MathNet.Symbolics.SymbolicExpression;
using static System.Console;
using static System.Numerics.Complex;
using Complex = System.Numerics.Complex;

namespace MathEvaluator
{
    class Program
    {
        static readonly Complex i = ImaginaryOne;

        static void Main(string[] args)
        {
            var z = Variable("z");
            Func<Complex, Complex> f = Parse("z * z").CompileComplex(nameof(z));
            Complex c = 1 / 2 - i / 3;
            WriteLine(f(c));


            var x = Variable("x");
            Func<double, double> g = Parse("x * x + 5 * x + 6").Compile(nameof(x));
            double a = 1 / 3.0;
            WriteLine(g(a));
        }
    }
}

लोड करने के लिए मत भूलना

<PackageReference Include="MathNet.Symbolics" Version="0.20.0" />
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.