Accrocchi per risolvere espressioni matematiche

Qualche tempo fa mi ero soffermato sul problema della risoluzione di espresioni matematiche. il problema non era per per un eigenza quindi non posso dire di avere trovato la soluzione definitiva/valida... quelo che posso fare è postare però gli esempi di codice che avevo prodotto - senza dubbio discutibili.

Prima dipartire mi era detto... arg certo che costruirmi un parser di epressioni matematiche sarebbe un bel casino e certo non ho ne tempo ne voglia, la sluzione migliore sarebbe quella di sfruttare i parser già esistenti. Quali? Quelli del framework! :D

Un primo parser e risolutore adatto per esperssioni relativamente semplici è quello del DataSet. La soluzione non è mia, l'avevo vista in http://www.codearchitects.com/, proposta da Francesco Balena & Co., ma poi ho anche trovato della documentazione su MSDN.

//Risolvere espressioni semplici con uso di variabili
using(DataSet ds = new DataSet())
{
    string Expression =  "((A + B) * 3) / 2";
    DataTable dt = ds.Tables.Add("MyExpression");
    dt.Columns.Add("A", Type.GetType("System.Decimal")); 
    dt.Columns.Add("B", Type.GetType("System.Decimal"));
    dt.Columns.Add("Result", Type.GetType("System.Decimal"), Expression);
    
    DataRow dr = dt.Rows.Add(new object[]{1, 2});    
    Console.WriteLine("{3}; A={1}, B={2} results {0}",  dr["Result"], dr["A"], dr["B"], Expression);
}

 

La soluzione è senza dubbio interessante, tuttavia non andava incontro a casi di espresioni particolarmente complesse con logaritmi, seni - non maliziate ;p - e coseni. La mia idea, con la quale tanto tempo fa avevo risposto sul Forum, è quella di usare il CodeDOM. Ecco il codice che avevo prodotto:

//Idea per come risolvere operazioni piu complesse anche se sarebbe meglio usare CodDom :(
//Potrebbero esserci delle CodeInjection... qndi dipende dall'uso da farsi e da chi è l'utilizzatore finale... etc etc... :p

string Expression = "SIN(45) + 1 + COS(90)";
string CodeExpression = Expression;
Type mt = Type.GetType("System.Math");
string[] MathFunctions = new String[mt.GetMethods().Length];
int i = 0;

foreach(MethodInfo m in mt.GetMethods())
{
     MathFunctions[i++] = m.Name; 
}

foreach(string MathFunction in MathFunctions)
{
      CodeExpression = Regex.Replace(CodeExpression, 
           MathFunction, string.Format("Math.{0}", MathFunction), RegexOptions.IgnoreCase);
}

StringBuilder sb = new StringBuilder();
sb.Append("using System;\n");
sb.Append("public class MyExpression{\n");
sb.Append("public static double Solve(){\n");
sb.Append("return ").Append(CodeExpression).Append(";\n");
sb.Append("}}");

CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler comp = provider.CreateCompiler();
CompilerParameters CompParam = new CompilerParameters();
CompParam.GenerateInMemory = true;
CompilerResults CompRes = comp.CompileAssemblyFromSource(CompParam, sb.ToString());
if(CompRes.Errors.Count > 0)
{
    foreach(CompilerError ce in CompRes.Errors){
    System.Console.WriteLine("{0}: {1}", ce.Line, ce.ErrorText);
}

Type t = CompRes.CompiledAssembly.GetType("MyExpression");
object result = t.InvokeMember("Solve", BindingFlags.InvokeMethod, null, null, null);
Console.WriteLine("{0} = {1}", Expression, result);

 

Di quest'ultima soluzione la cosa che mi lascia un po perplesso è l'algoritmo per fare il mapping tra la funzioni usate nell'espresione e quelle di System.Math...
Oh si è vero in questa soluzione non sembra esserci posto per le variabili... nella mia testa la solzuione era piu macchinosa... qndo la metto in piedi la bloggo :p

Altra soluzione potrebbe essere qualla di definire la classe MyExpressionBase che definisce tutte le funzioni che si vogliono mettere a disposizione (ovviamante protette). La classe MyExpression che costruiamo ancora al volo questa volta eredita da MyExpressionBase... :p

posted @ venerdì 17 ottobre 2003 12:32

Print

Comments on this entry:

# re: Accrocchi per risolvere espressioni matematiche

Left by M.rkino at 13/07/2007 13:15
Gravatar
Il post - oltretutto datato - vuole fornire un modo per sviluppatori .NET per risolvere espressioni matematiche o introdurre la riluzione di proprie espressioni...

Avrei in cantiere un articolo che approfondisce l'argomento usando CodDom ma sia chiaro che le argomentazioni da me trattare in questo post e nell'eventuale articolo sono rivolte ad un pubblico di sviluppatori .NET

Se vi occorre un programma o un servzio on line per risolvere espressioni matematiche questo non è il posto dove cercare.

# re: Accrocchi per risolvere espressioni matematiche

Left by giovanna at 20/09/2007 19:20
Gravatar
[(1/3-1/4)elevato alla2x10alla2(1+4/5)alla2](2-1/2)alla2
potete risolvermela grazie

# re: Accrocchi per risolvere espressioni matematiche

Left by chiara at 21/09/2007 22:34
Gravatar
la matematica non è il mio forte, da grande non voglio diventare scienziata o ingegnere ma cantantre quindi nn è ke mi serve molto però per non avere l'insufficenza a scuola ho bisogno del vostro aiuto! fare un sito dove si digita l'esopressione e il computer la risolve grazie vi amo spero che mi ascoltiate! ciò che sembra può swembrare sciocco ma non è carino non sapere fare l'espressioni e poi se ci riflettiamo la matematica non ha molta importanza ciaoooooooo

# re: Accrocchi per risolvere espressioni matematiche

Left by M.rkino at 24/09/2007 10:04
Gravatar
Chiara sarebbe carino che studiassi, sarebbe bello che imparassi a scrivere bene anche in italiano, sarebbe carino che le tue frasi non sembrassero quelle di una ragazzina di 5 anni. Ripeto questo è un blog tecnico per programmatori .NET. Il post è del 2003 e andrebbe rivisto. Questo NON è un sito per aiutare studenti e soprattutto NON è mia intenzione aiutare studenti che vogliono rimanere somari!

# re: Accrocchi per risolvere espressioni matematiche

Left by maria at 13/10/2007 18:53
Gravatar
come risolvere l'espressioni con potenza e esponente negativo

# re: Accrocchi per risolvere espressioni matematiche

Left by M.rkino at 15/10/2007 20:04
Gravatar
PRIMA DI POSTARE IL PROSSIMO COMMENTO RICORDO CHE QUESTO NON E' UN FORUM. CHI NECESSITA DI RISOLVERE I PROPRI PROBLEMI SCOLASTICI NON REALTIVI ALLA PROGRAMMAZIONE E' PREGATO DI CERCARE ALTROVE! GRAZIE!

PS: Mio dio! "ci sta un sito"... purtroppo so già che NON è stata una licenza poetica :(

# re: Accrocchi per risolvere espressioni matematiche

Left by M.rkino at 22/10/2007 19:49
Gravatar
Spiacente, chiudo i commenti.
Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011