যদি আমার কাছে বৈধ গণিতের এক্সপ্রেশন সহ একটি স্ট্রিং থাকে যেমন:
String s = "1 + 2 * 7";
.NET- এ এমন কোনও লাইব্রেরি / ফাংশন অন্তর্নিহিত রয়েছে যা আমার জন্য সেই অভিব্যক্তিটিকে বিশ্লেষণ ও মূল্যায়ন করবে এবং ফলাফলটি ফিরিয়ে দেবে? এই ক্ষেত্রে 15।
যদি আমার কাছে বৈধ গণিতের এক্সপ্রেশন সহ একটি স্ট্রিং থাকে যেমন:
String s = "1 + 2 * 7";
.NET- এ এমন কোনও লাইব্রেরি / ফাংশন অন্তর্নিহিত রয়েছে যা আমার জন্য সেই অভিব্যক্তিটিকে বিশ্লেষণ ও মূল্যায়ন করবে এবং ফলাফলটি ফিরিয়ে দেবে? এই ক্ষেত্রে 15।
উত্তর:
আপনি মাইক্রোসফ্ট স্ক্রিপ্ট কন্ট্রোল লাইব্রেরিতে (সিওএম) একটি রেফারেন্স যুক্ত করতে পারেন এবং একটি এক্সপ্রেশন মূল্যায়নের জন্য এই জাতীয় কোড ব্যবহার করতে পারেন। (জেএসক্রিপ্টের জন্যও কাজ করে))
Dim sc As New MSScriptControl.ScriptControl()
sc.Language = "VBScript"
Dim expression As String = "1 + 2 * 7"
Dim result As Double = sc.Eval(expression)
সম্পাদনা করুন - সি # সংস্করণ।
MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl();
sc.Language = "VBScript";
string expression = "1 + 2 * 7";
object result = sc.Eval(expression);
MessageBox.Show(result.ToString());
সম্পাদনা করুন - স্ক্রিপ্টকন্ট্রোল একটি COM অবজেক্ট। প্রকল্পের "রেফারেন্স যুক্ত করুন" সংলাপে "COM" ট্যাবটি নির্বাচন করুন এবং "মাইক্রোসফ্ট স্ক্রিপ্ট নিয়ন্ত্রণ 1.0" এ স্ক্রোল করুন এবং ঠিক আছে নির্বাচন করুন select
আশ্চর্যের বিষয় যে এই বিখ্যাত এবং পুরানো প্রশ্নের কোনও উত্তর নেই যা অন্তর্নির্মিত DataTable.Compute- "কৌশল" বোঝায় । এটা এখানে.
double result = Convert.ToDouble(new DataTable().Compute("1 + 2 * 7", null));
নিম্নলিখিত গণিত অপারেটরগুলি এক্সপ্রেশন সমর্থন করে:
+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulus)
আরও তথ্য: DataColumn.Expressionএ এক্সপ্রেশন সিনট্যাক্স ।
সিলভারলাইটে সি # তে যে কারও বিকাশের জন্য এখানে একটি সুন্দর ঝরঝরে কৌশল আমি সবেমাত্র আবিষ্কার করেছি যা জাভাস্ক্রিপ্ট ইঞ্জিনে ডেকে একটি অভিব্যক্তির মূল্যায়নের অনুমতি দেয়:
double result = (double) HtmlPage.Window.Eval("15 + 35");
আপনি http://ncalc.codeplex.com দেখেছেন ?
এটি এক্সটেনসিবল, দ্রুত (উদাহরণস্বরূপ নিজস্ব নিজস্ব ক্যাশে রয়েছে) আপনাকে EvaluateFunction / EvaluateParameter ইভেন্টগুলি পরিচালনা করে রান সময় কাস্টম ফাংশন এবং ভেরিয়েবল সরবরাহ করতে সক্ষম করে। এটি প্রকাশ করতে পারে এমন উদাহরণের উদাহরণ:
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());
এটি ইউনিকোড এবং অনেকগুলি ডেটা দেশীয়ভাবে পরিচালনা করে। আপনি ব্যাকরণ পরিবর্তন করতে চাইলে এটি একটি এন্টলার ফাইলের সাথে আসে। এছাড়াও একটি কাঁটাচামচ রয়েছে যা নতুন ফাংশনগুলি লোড করতে এমইএফ সমর্থন করে।
আসলে একটির মধ্যে একটি বিল্টের ধরণ রয়েছে - আপনি এক্সপথ নেমস্পেস ব্যবহার করতে পারেন! যদিও এটি প্রয়োজন যে আপনি এক্সপথ স্বরলিপি দিয়ে নিশ্চিত করতে স্ট্রিংটির পুনরায় ফর্ম্যাট করুন। আমি সাধারণ অভিব্যক্তি পরিচালনা করতে এই জাতীয় পদ্ধতি ব্যবহার করেছি:
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);
}
প্রাথমিকভাবে আমি মুপারসারের জন্য সি # র্যাপার ব্যবহার করেছি । এটি খুব দ্রুত ছিল। আমি জানি দ্রুততম সমাধানটি এক্সপ্রেটক । আপনি যদি অন্য সমাধানগুলির সন্ধান করেন তবে আপনি বেঞ্চমার্কটি চেকআউট করতে পারেন ।
তবে। নেট এর ক্ষেত্রে আপনি রানটাইম সময়ে কোডটি সংকলনের জন্য বিল্টিন সমর্থনটি ব্যবহার করতে পারেন। ধারণাটি একটি "টেম্পলেট" উত্স ফাইল হিসাবে থাকা যেমন এম্বেড থাকা সংস্থান যেখানে আপনি মূল্যায়নের সূত্রটি প্রতিস্থাপন করতে পারেন। তারপরে আপনি এই প্রস্তুত ক্লাস-উত্স-কোডটি সংকলককে পাস করুন।
একটি প্রাথমিক টেমপ্লেট এটি দেখতে পারে:
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 শ্রেণিটি ব্যবহার করুন। আমি এখানে সম্পূর্ণ উত্স স্থাপন করতে চাই না। তবে এই উত্তরটি সাহায্য করতে পারে:
আপনি মেমরি অ্যাসেম্বলি লোড করার পরে আপনি আপনার শ্রেণীর উদাহরণ তৈরি করতে পারেন এবং ইভালকোড কল করতে পারেন।
রোজলিন এখন আর একটি বিকল্প উপলব্ধ:
আপনি এর জন্য কোডএনালাইসিস.সিএসআরপি.স স্ক্রিপ্টিং লাইব্রেরি ব্যবহার করতে পারেন।
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();
}
}
}
nuget প্যাকেজ:
<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" />
সম্প্রতি আমি এমএক্সপার্সার ব্যবহার করছিলাম যা। নেট এবং জাভা জন্য গণিত পার্সার লাইব্রেরি। এমএক্সপারসার বেসিক সূত্রগুলির পাশাপাশি খুব অভিনব / জটিল বিষয়গুলিকে (ভেরিয়েবল, ফাংশন, অপারেটর, পুনরাবৃত্তি এবং পুনরাবৃত্তি সহ) সমর্থন করে।
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();
সম্প্রতি পাওয়া গেছে - যদি আপনি সিনট্যাক্সটি চেষ্টা করতে চান (এবং উন্নত ব্যবহারের ক্ষেত্রে দেখুন) আপনি এমএক্সপারসার দ্বারা চালিত স্কেলার ক্যালকুলেটর অ্যাপ্লিকেশনটি ডাউনলোড করতে পারেন ।
শুভেচ্ছান্তে
আপনার যদি খুব সাধারণ জিনিসের প্রয়োজন হয় তবে আপনি 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")
আমি জেস ( https://github.com/pieterderycke/Jace ) এও নজর দেব । জেস একটি উচ্চতর পারফরম্যান্স ম্যাথ পার্সার এবং গণনা ইঞ্জিন যা সমস্ত .NET স্বাদ সমর্থন করে (। নেট 4.x, উইন্ডোজ ফোন, উইন্ডোজ স্টোর, ...)। জেস নুগেটের মাধ্যমেও উপলব্ধ: 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
}
}
}
আমি কয়েক বছর আগে একটি এক্সপ্রেশন পার্সার প্রয়োগ করেছি এবং এটির একটি সংস্করণ গিটহাব এবং নুগেট: আলবাট্রস.এক্সপ্রেসনে সম্প্রতি প্রকাশ করেছি। এটিতে একটি এক্সিকিউশন কনটেক্সট ক্লাস রয়েছে যা এক্সপ্রেশনগুলির সেটকে মূল্যায়ন করতে পারে যেমন:
এটি বৃত্তাকার রেফারেন্স চেকও তৈরি করেছে যা স্ট্যাকের অতিরিক্ত প্রবাহ এড়াতে কার্যকর is
আমি গণিত-এক্সপ্রেশন-মূল্যায়নকারী লাইব্রেরিটি ব্যবহার করতে পারি যেটির আমি লেখক। এটা সহজ এক্সপ্রেশন সমর্থন যেমন 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);
এটি নেট স্ট্যান্ডার্ড 2.0 সমর্থন করে তাই নেট কোর পাশাপাশি নেট নেট ফ্রেমওয়ার্ক প্রকল্পগুলি থেকে ব্যবহার করা যায় এবং এর কোনও বাহ্যিক নির্ভরতা নেই।
দ্রুত পাল্টা হালকা এক্সপ্রেশন মূল্যায়নকারী
ভাষার উল্লেখ
উদাহরণ:
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" />