अगर मेरे पास एक मान्य गणित अभिव्यक्ति के साथ एक स्ट्रिंग है जैसे:
String s = "1 + 2 * 7";
क्या .NET / लाइब्रेरी में एक ऐसा फ़ंक्शन है जो .NET में बनेगा और मेरे लिए उस एक्सप्रेशन का मूल्यांकन करेगा और परिणाम देगा? इस मामले में 15।
अगर मेरे पास एक मान्य गणित अभिव्यक्ति के साथ एक स्ट्रिंग है जैसे:
String s = "1 + 2 * 7";
क्या .NET / लाइब्रेरी में एक ऐसा फ़ंक्शन है जो .NET में बनेगा और मेरे लिए उस एक्सप्रेशन का मूल्यांकन करेगा और परिणाम देगा? इस मामले में 15।
जवाबों:
आप 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" पर स्क्रॉल करें और ठीक चुनें।
अजीब बात है कि इस प्रसिद्ध और पुराने सवाल का कोई जवाब नहीं है जो बिलिन का सुझाव देता है DataTable.Compute- "चाल"। यही पर है।
double result = Convert.ToDouble(new DataTable().Compute("1 + 2 * 7", null));
निम्नलिखित अंकगणितीय संचालकों को अभिव्यक्तियों में समर्थन दिया जाता है:
+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulus)
अधिक जानकारियां: DataColumn.Expressionपर अभिव्यक्ति सिंटेक्स ।
सिल्वरलाइट पर C # में किसी को भी विकसित करने के लिए यहाँ एक बहुत साफ चाल है जिसे मैंने अभी-अभी खोजा है जो जावास्क्रिप्ट इंजन को कॉल करके अभिव्यक्ति के मूल्यांकन की अनुमति देता है:
double result = (double) HtmlPage.Window.Eval("15 + 35");
क्या आपने 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 का समर्थन करता है।
वास्तव में एक तरह से बनाया गया है - आप 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);
}
प्रारंभ में मैंने 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 को कॉल कर सकते हैं।
अभी तक एक और विकल्प है कि रोसलिन उपलब्ध है:
इसके लिए आप 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" />
हाल ही में मैं mXparser का उपयोग कर रहा था, जो .NET और JAVA के लिए एक गणित पार्सर लाइब्रेरी है। mXparser बुनियादी फ़ार्मुलों के साथ-साथ बहुत फैंसी / जटिल लोगों (चर, कार्यों, ऑपरेटरों, पुनरावृत्ति और पुनरावृत्ति सहित) का समर्थन करता है।
https://mxparser.codeplex.com/
कुछ उपयोग उदाहरण:
उदाहरण 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 द्वारा संचालित है।
सादर
यदि आपको बहुत ही सरल चीज़ की आवश्यकता है तो आप 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")
मैं Jace ( https://github.com/pieterderycke/Jace ) पर भी नज़र डालूंगा । Jace एक उच्च प्रदर्शन गणित पार्सर और गणना इंजन है जो सभी .NET फ्लेवर (.NET 4.x, विंडोज फोन, विंडोज स्टोर, ...) का समर्थन करता है। Jace NuGet: https://www.nuget.org/packages/Jace के माध्यम से भी उपलब्ध है
एक साधारण गणित पार्सर बनाने में काफी आसान है, और इसके लिए केवल कुछ लाइनों की आवश्यकता होती है:
इस लचीले उदाहरण को लें:
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
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
}
}
}
मैंने कुछ साल पहले एक अभिव्यक्ति पार्सर लागू किया था और हाल ही में GitHub और Nuget: Albatross.Expression में इसका एक संस्करण प्रकाशित किया था । इसमें एक एक्ज़ेक्यूशन कोटेक्स्ट क्लास शामिल है जो कि अभिव्यक्ति के एक सेट का मूल्यांकन कर सकता है जैसे:
यह परिपत्र संदर्भ जांच में भी बनाया गया है जो स्टैक ओवरफ्लो से बचने के लिए उपयोगी है।
आप मैथ-एक्सप्रेशन-इवैल्यूएटर लाइब्रेरी का उपयोग कर सकते हैं जो मैं लेखक हूं। यह सरल भाव का समर्थन करता है जैसे 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 फुल फ्रेमवर्क प्रोजेक्ट्स से भी किया जा सकता है और इसमें कोई बाहरी निर्भरता नहीं है।
फ्ली फास्ट लाइटवेट एक्सप्रेशन इवैल्यूएटर
भाषा संदर्भ
उदाहरण :
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
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" />