.NET- এ স্ট্রিং ম্যাথের মূল্যায়নকারী আছে?


95

যদি আমার কাছে বৈধ গণিতের এক্সপ্রেশন সহ একটি স্ট্রিং থাকে যেমন:

String s = "1 + 2 * 7";

.NET- এ এমন কোনও লাইব্রেরি / ফাংশন অন্তর্নিহিত রয়েছে যা আমার জন্য সেই অভিব্যক্তিটিকে বিশ্লেষণ ও মূল্যায়ন করবে এবং ফলাফলটি ফিরিয়ে দেবে? এই ক্ষেত্রে 15।


4
একটিতে নির্মিত না। তবে এখানে বেশ বিস্তৃত রয়েছে ।
— স্ট্র্লোক


4
আপনি এক্সপ্রেশন মূল্যায়নকারী (100% পরিচালিত। নেট)
— এভাল

আমি কেবল সি # তে গাণিতিক এক্সপ্রেশন মূল্যায়নের জন্য একটি কোড-কেবল সমাধান তৈরি করেছি। আপনি কোডটি ব্ল্যাকবেলটকোডার / আর্টিকেলস / অ্যালগোরিদমস / এ্যাক-এক্সপ্রেশন- ইভালুয়েটারে দেখতে পারেন ।
— জোনাথন উড

এই লাইব্রেরিতে কিছু বাগ রয়েছে বলে মনে হচ্ছে।
— ফিলিপ লাভোই

উত্তর:


53

আপনি মাইক্রোসফ্ট স্ক্রিপ্ট কন্ট্রোল লাইব্রেরিতে (সিওএম) একটি রেফারেন্স যুক্ত করতে পারেন এবং একটি এক্সপ্রেশন মূল্যায়নের জন্য এই জাতীয় কোড ব্যবহার করতে পারেন। (জেএসক্রিপ্টের জন্যও কাজ করে))

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


4
যদিও এটির উত্তর হিসাবে চিহ্নিত করা হয়েছে, এটি 10 ​​বছর আগে ছিল এবং সিওএম এখন এক ধরণের মৃত। আমি নীচে 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 নভেম্বর '11 এ ma81xx থেকে একটি উত্তর ছিল
— তাতিগো

4
আপনি ঠিক বলেছেন, কিন্তু এটি গণনা পদ্ধতিটি ব্যবহার করছিল না।
— টিম শ্মেলটার

আপনার উদাহরণটি আমাকে সিস্টেম দেয় nঅনুপাতিক কাস্টএক্সসেপশনটি ব্যবহারকারী কোড এইচআরসাল্ট = -2147467262 দ্বারা নিয়ন্ত্রণহীন ছিল আমি কীভাবে এটি সংশোধন করতে পারি?
— ইউলিয়া আশোমক

এটি আমার পক্ষে কাজ করে, আপনি কি এই নমুনা কোডটি ব্যবহার করেছেন? ডিবাগারটি ব্যবহার করুন এবং ফলাফলের মানটি পরীক্ষা করুন, প্রকারটি উল্লেখ করা হয়েছে।
— টিম শেমলেটার

28

সিলভারলাইটে সি # তে যে কারও বিকাশের জন্য এখানে একটি সুন্দর ঝরঝরে কৌশল আমি সবেমাত্র আবিষ্কার করেছি যা জাভাস্ক্রিপ্ট ইঞ্জিনে ডেকে একটি অভিব্যক্তির মূল্যায়নের অনুমতি দেয়:

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

আমি ভাবছি যদি আপনি এটি অন্য কোথাও উল্লেখ করতে পারেন। সম্ভবত না, তবে এটি দুর্দান্ত হবে।
— জোয়েল কোহর্ন 15

4
যেহেতু এটি স্বেচ্ছাসেবী জাভাস্ক্রিপ্ট কোডটিকে মূল্যায়ন করে, আপনি সম্ভবত নিজের ইনপুটটি স্যানিটাইজ করতে এবং আপনি সরাসরি ফলাফলটি প্রদর্শন করছেন না তা নিশ্চিত হতে চান। (আমি মনে করি এটি এক্সএসএস না বুঝে প্রবর্তন করার ভাল উপায় হবে)
— ড্যান এস্পারজা

একটি নেতৃস্থানীয় শূন্য সহ সংখ্যা প্রবেশ করানোর চেষ্টা করুন, ফলাফল নির্ভরযোগ্য নয়। "054 + 6" উদাহরণস্বরূপ আপনাকে 50 দেয়।
— টেরি

9
@djerry, কারণ একটি নেতৃস্থানীয় শূন্য দিয়ে সংখ্যার জাতীয় এর evaluator দ্বারা অকট্যাল বলে মনে করা হয় যে, এবং অকট্যাল 054 সমান 44. দশমিকে
— আঁদ্রে Leria

24

আপনি 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()); 

এটি ইউনিকোড এবং অনেকগুলি ডেটা দেশীয়ভাবে পরিচালনা করে। আপনি ব্যাকরণ পরিবর্তন করতে চাইলে এটি একটি এন্টলার ফাইলের সাথে আসে। এছাড়াও একটি কাঁটাচামচ রয়েছে যা নতুন ফাংশনগুলি লোড করতে এমইএফ সমর্থন করে।


4
দুর্দান্ত গ্রন্থাগার। নাগেটেও উপলব্ধ
— পল গ্রিমশো

এটিই আমি আমার ডিফারেনশিয়াল সমীকরণ সলভারের জন্য ব্যবহার করেছি যা ব্যবহারকারীর ইনপুট নেয়। প্রশ্ন হল এখানে
— kleineg

15

আসলে একটির মধ্যে একটি বিল্টের ধরণ রয়েছে - আপনি এক্সপথ নেমস্পেস ব্যবহার করতে পারেন! যদিও এটি প্রয়োজন যে আপনি এক্সপথ স্বরলিপি দিয়ে নিশ্চিত করতে স্ট্রিংটির পুনরায় ফর্ম্যাট করুন। আমি সাধারণ অভিব্যক্তি পরিচালনা করতে এই জাতীয় পদ্ধতি ব্যবহার করেছি:

    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

প্রাথমিকভাবে আমি মুপারসারের জন্য সি # র‌্যাপার ব্যবহার করেছি । এটি খুব দ্রুত ছিল। আমি জানি দ্রুততম সমাধানটি এক্সপ্রেটক । আপনি যদি অন্য সমাধানগুলির সন্ধান করেন তবে আপনি বেঞ্চমার্কটি চেকআউট করতে পারেন ।

তবে। নেট এর ক্ষেত্রে আপনি রানটাইম সময়ে কোডটি সংকলনের জন্য বিল্টিন সমর্থনটি ব্যবহার করতে পারেন। ধারণাটি একটি "টেম্পলেট" উত্স ফাইল হিসাবে থাকা যেমন এম্বেড থাকা সংস্থান যেখানে আপনি মূল্যায়নের সূত্রটি প্রতিস্থাপন করতে পারেন। তারপরে আপনি এই প্রস্তুত ক্লাস-উত্স-কোডটি সংকলককে পাস করুন।

একটি প্রাথমিক টেমপ্লেট এটি দেখতে পারে:

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 শ্রেণিটি ব্যবহার করুন। আমি এখানে সম্পূর্ণ উত্স স্থাপন করতে চাই না। তবে এই উত্তরটি সাহায্য করতে পারে:

আপনি মেমরি অ্যাসেম্বলি লোড করার পরে আপনি আপনার শ্রেণীর উদাহরণ তৈরি করতে পারেন এবং ইভালকোড কল করতে পারেন।


9

রোজলিন এখন আর একটি বিকল্প উপলব্ধ:

আপনি এর জন্য কোডএনালাইসিস.সিএসআরপি.স স্ক্রিপ্টিং লাইব্রেরি ব্যবহার করতে পারেন।

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" />

4
এটি এখনই উত্তর হওয়া উচিত
— Sonofaforester

8

সম্প্রতি আমি এমএক্সপার্সার ব্যবহার করছিলাম যা। নেট এবং জাভা জন্য গণিত পার্সার লাইব্রেরি। এমএক্সপারসার বেসিক সূত্রগুলির পাশাপাশি খুব অভিনব / জটিল বিষয়গুলিকে (ভেরিয়েবল, ফাংশন, অপারেটর, পুনরাবৃত্তি এবং পুনরাবৃত্তি সহ) সমর্থন করে।

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();

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

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


এটি আমার পাওয়া সেরা গ্রন্থাগার। তবে এটি সংখ্যা ছাড়া অন্য কোনও ডেটা টাইপ সমর্থন করে না! আমার ডেটটাইম এবং স্ট্রিং দরকার .. আপনি কি কোনও ভাল বিকল্প জানেন?
— হোমাম

@ হোমাম আপনি কি স্ট্রিং অপারেশনের বিকল্প খুঁজে পেয়েছেন
— রামকৃষ্ণ রেড্ডি

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

আমি জেস ( https://github.com/pieterderycke/Jace ) এও নজর দেব । জেস একটি উচ্চতর পারফরম্যান্স ম্যাথ পার্সার এবং গণনা ইঞ্জিন যা সমস্ত .NET স্বাদ সমর্থন করে (। নেট 4.x, উইন্ডোজ ফোন, উইন্ডোজ স্টোর, ...)। জেস নুগেটের মাধ্যমেও উপলব্ধ: 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
        }

    }
}

4
-1: কেবল এটি @ সিবিপি উত্তরে মার্জ করুন। জিরোর দুটি উত্তর থাকা দরকার যা মূলত অভিন্ন, যখন আমরা একটি দুর্দান্ত উত্তর পেতে পারি।
— রবার্ট ম্যাকলিয়ান

1

আমি কয়েক বছর আগে একটি এক্সপ্রেশন পার্সার প্রয়োগ করেছি এবং এটির একটি সংস্করণ গিটহাব এবং নুগেট: আলবাট্রস.এক্সপ্রেসনে সম্প্রতি প্রকাশ করেছি। এটিতে একটি এক্সিকিউশন কনটেক্সট ক্লাস রয়েছে যা এক্সপ্রেশনগুলির সেটকে মূল্যায়ন করতে পারে যেমন:

  • এমভি = দাম * পরিমাণ;
  • মূল্য = (বিড + জিজ্ঞাসা) / 2;
  • বিড = .6;
  • জিজ্ঞাসা করুন = .8;

এটি বৃত্তাকার রেফারেন্স চেকও তৈরি করেছে যা স্ট্যাকের অতিরিক্ত প্রবাহ এড়াতে কার্যকর is


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);

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


0

দ্রুত পাল্টা হালকা এক্সপ্রেশন মূল্যায়নকারী

https://flee.codeplex.com

ভাষার উল্লেখ

  • গাণিতিক অপারেটর উদাহরণ: একটি * 2 + বি ^ 2 - 100% 5
  • তুলনা অপারেটর উদাহরণ: একটি <> 100
  • AndOrXorNotOperators উদাহরণ (যৌক্তিক): এ> 100 এবং বি = 100 নয়
  • শিফটঅ্যাপেরেটর উদাহরণ: 100 >> 2
  • সংঘবদ্ধকরণ উদাহরণ: "abc" + "Def"
  • সূচকের উদাহরণ: আরআর [i + 1] + 100
  • সাহিত্যের
  • কাস্টিং উদাহরণ: 100 + castালাই (আপত্তি, ইনট)
  • শর্তাধীন অপারেটর উদাহরণ: (a> 100 এবং b> 10, "উভয় বৃহত্তর", "কম")
  • ইনওপ্রেটার উদাহরণ (তালিকা): যদি (100 ইন (100, 200, 300, -1), "ইন", "ইন" নয়)
  • প্রকারভেদে ওভারলোডেড অপারেটরগণ

উদাহরণ:

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

ম্যাথনেট.সিম্বলিক্স

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" />
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.