Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : [VB.Net 2003] Expression littérales [ Algorithme / Maths ] (MoiDebutantVB)

mardi 19 septembre 2006 à 17:28:37 | [VB.Net 2003] Expression littérales

MoiDebutantVB

Bonjour,
Est il possible de, sans dévelloper un moteur d'analyse complet, d'interpréter une expression littérale en VB.Net ?
Par exemple, l'utilisateur tape 2x^2+3x+5 et entre x=5 dans une autre case et le programme calcule 2x^2+3x+5 en utilisant la valeur de x (5) entrée.
Sinon, Savez vous si des codes similaires existent ?
Et finalement, si non, pourriez vous me donner des pistes pour écrire moi-même un analyseur ?

Merci beacoup en tout cas,
 CFP

Essayez les ReyComponents de renfield !!!

mardi 19 septembre 2006 à 23:27:25 | Re : [VB.Net 2003] Expression littérales

RedDog

Salut,
Essaye avec des expressions régulières (Regex), voilà l'indice.
Comme ça tu pourras repérer des expressions types et les résoudre assez facilement avec les formules de maths que tu as appris.
Sinon, cherche un peu sur ce site ou ailleurs....
Courage

mercredi 20 septembre 2006 à 17:16:07 | Re : [VB.Net 2003] Expression littérales

MoiDebutantVB

Je comprend pas vraiment...

Essayez les ReyComponents de renfield !!!

mercredi 20 septembre 2006 à 21:40:12 | Re : [VB.Net 2003] Expression littérales

RedDog

Et bien pour une expression telle que:

ax²+bx+c

On va par l'intermédiaire d'un pattern reconnaître la forme de l'équation et vouloir récupérer a, b et c afin de résoudre l'équation.

Après, si on a x=5, on fait le calcul dans un fonction spécifique.

De même, on aurait ax²+bx+c=0. Après, on peut appliquer les formules de maths dans une autre fonction.

Pour identifier ax²+bx+c=0 avec c>0 par exemple, le pattern serait (je te laisse chercher pourquoi? et s'il y a une erreur, désolé):

[0-9]*x²\+[0-9]*x\+[0-9]+=0
ou plus simplement:
\d*x²\+\d*x\+\d+=0

Si dans l'équation ax²=b, on veut chercher a, on le prendrait comme çà (là aussi je te laisse chercher pourquoi?):

(?<"variable">\d*)x²=\d*; a est récupéré à l'aide du mot clé.

Une fois qu'on a notre 'variable' On peut faire les calculs qu'on veut.

Un exemple qui vient d'une de mes dernières applications, j'ai mis un texte assez simple de façon à rendre l'exemple explicite, cela fait partie d'une méthode capable de calculer des expressions mathématiques avec parenthèses dans une phrase.

Imports
System.Text.RegularExpressions

(...)

        Dim texte AsString = "14*20"
        Dim reg As Regex
        Dim m As MatchCollection

        Try ' On fait une multiplication
            ' Le pattern représente une expression a*b et peut-être entre parenthèses
            reg = New Regex("\(?(?<1>-?\d+)\*(?<2>-?\d+)\)?")
            ' On recherche avec Match
            m = reg.Matches(texte)
            ' Ce bout de code est fait pour calculer toutes les multiplications qu'on
            ' aurait pu trouver dans une phrase, d'où la boucle (r1 et r2 sont des String)

            For i As Integer = m.Count - 1 To 0 Step -1
                Dim rm As Match = m.Item(i)
                r1 = rm.Groups(1).ToString ' Récupère la valeur de (?<1>-?\d+)
                r2 = rm.Groups(2).ToString
                Dim ir As Integer = CInt(r1) * CInt(r2) ' Cast et multiplication
               
                (...)

            Next
        Catch ex As Exception
            MessageBox.Show(ex.StackTrace _
            , "Erreur dans la méthode de calcul avec regex > multiplication" _
            , MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
        End Try

Voilà, sinon expose-nous ton code si tu as des problèmes!

vendredi 22 septembre 2006 à 19:19:28 | Re : [VB.Net 2003] Expression littérales

MoiDebutantVB

Ok mais comment je fais si l'expression c'est [(Cos(x) + x/2)^3]*(2x^2 - 1), par exemple...
Merci de ton aide en tout cas...

vendredi 22 septembre 2006 à 20:38:10 | Re : [VB.Net 2003] Expression littérales

RedDog

Comment faire si c'est pas une expression types? C'est ça? Si on maths on nous pose cette équation (cos(x) + x/2)3*(2x² - 1) et si on connait la valeur de x alors je préconiserais, à tord ou à raison j'en sais rien, d'essayer de traiter ça par bloc, de la même manière qu'en maths en repérant les expressions connues avec le pattern leur correspondant.

D'abord un bloc, puis ensuite l'autre,... et pour finir la multiplication, le tout en Single pour être précis.

Après, soit on gère les résultat et ce qui nous reste à calculer avec des variables, soit on choisit la méthodes feignant comme c'est le cas dans ma fonction récursive, en remplaçant dans la chaine d'origine l'opération effectué par son résultat et on tenant compte des signes "+" à rajouter si on doit encore calculer autre chose.

Si x n'est pas connue, pourquoi ne pas tenter une résolution graphique, comme en maths quoi.

mercredi 27 septembre 2006 à 19:45:07 | Re : [VB.Net 2003] Expression littérales

MoiDebutantVB

J'ai fait ce code : 


    Public Function Résoudre(ByVal Expression AsString, ByVal ValeurX AsSingle) AsSingle

        Dim Résultat AsSingle = 0 
        Dim Exp AsNew Regex("[(](.[*/]?[x])[)]([+-*/])[(](.[*/]?[x])[)]")


je ne suis pas sur de mon expression : j'ai trouvé un article de wikipédia mais je dout quand même : Ce que je veux dire c'est que  on a :
un ensemble d'un nombre, d'un symbole * ou diviser, et d'un autre nombre, le tout entre () ;
suivi de soit + soit - soit * soit / ;
puis un autre ensemble équivalent au premier, lui aussi encadré par des parenthèses.

Ensuite je traite l'expression :


        Dim Partie_Calculée AsSingle

        If Exp.Matches(Expression).Count > 0 Then'Si il y a plusieurs parties...

            For Each SousExpression As Match In Exp.Matches(Expression) 'Pour chaque sous-partie

                Select Case SousExpression.Groups(2).ToString

                    Case "+"

                        Partie_Calculée = Résoudre(SousExpression.Groups(1).ToString, ValeurX) + Résoudre(SousExpression.Groups(3).ToString, ValeurX) 'A chaque fois on décompose le sous-ensemble

                     Case "-"

                        Partie_Calculée = Résoudre(SousExpression.Groups(1).ToString, ValeurX) - Résoudre(SousExpression.Groups(3).ToString, ValeurX)

                    Case "*"

                        Partie_Calculée = Résoudre(SousExpression.Groups(1).ToString, ValeurX) * Résoudre(SousExpression.Groups(3).ToString, ValeurX)

                    Case "/"

                        Partie_Calculée = Résoudre(SousExpression.Groups(1).ToString, ValeurX) / Résoudre(SousExpression.Groups(3).ToString, ValeurX)

                End Select

                Résultat *= Partie_Calculée 'On ajoute au résultat la valeur du calcul de chaque partie

            Next

        End If

        Return Résultat 'On retourne le résultat


 Pourriez-vous s'il vous plait corriger les éventuelles erreurs de mon code et de ma RegExp? Merci beaucoup pour votre aide à tous !

Essayez les ReyComponents de renfield !!!

mercredi 27 septembre 2006 à 19:47:30 | Re : [VB.Net 2003] Expression littérales

MoiDebutantVB

Désolé le code n'est ni coloré ni dans la bonne police pourtant ca marchait dans ma saisie du message...

Essayez les ReyComponents de renfield !!!

jeudi 28 septembre 2006 à 04:45:50 | Re : [VB.Net 2003] Expression littérales

RedDog

Bon d'abord, je décortique ton expression à ma manière:

le tout entre ():
\(' Une parenthèse d'ouverture (avec obligation d'utiliser un backslash pour la déclarer)

un ensemble d'un nombre:
\d+' Qui veut dire qu'on a un nombre >= 1

d'un symbole * ou diviser:
[\*/]' Un multiplié (avec obligation d'utiliser un backslash pour le déclarer) ou un divisé

et d'un autre nombre:
\d+' Qui veut dire qu'on a un nombre >= 1

le tout entre ():
\)' Une parenthèse de fermeture (avec obligation d'utiliser un backslash pour la déclarer)

suivi de soit + soit - soit * soit / :
[\*\+-/]' multiplication ou addition ou soustraction ou division

puis un autre ensemble équivalent au premier, lui aussi encadré par des parenthèses:
\(\d+[\*/]\d+\)


ex:
Dim r AsNew Regex("\(\d+[\*/]\d+\)[\*\+-/]\(\d+[\*/]\d+\)")
Dim mc As MatchCollection = r.Matches("(3*6)+(2*3)-(4*20)*(2*10)")
ForEach m As Match In mc
    Console.WriteLine("Chaine trouvé: " & m.ToString)
Next

Retourne:
Chaine trouvé: (3*6)+(2*3)
Chaine trouvé: (4*20)*(2*10)


Après je regarde ton expression: [(](.[*/]?[x])[)]([+-*/])[(](.[*/]?[x])[)]

Bon déjà, il n'y a aucun backslash devant les caractères spéciaux qui sont de ce type: . $ ^ { [ ( | ) * + ? \
Va voir la documentation sur MSDN en anglais ou en français, à ton aise.

Ensuite quand on a un endroit avec un seul caractère à déclarer, il est inutile de l'encadrer: [(] devient ( mais devient également \( car c'est un caractère spécial, donc au début on a \( et à la fin on a \)

Si on simplifie l'expression avec ces considérations, on a: \((.[\*/]?x)\)([\*\+-/])\((.[\*/]?x)\)
Cette expression marche déjà mieux que celle d'avant qui bloquait.

ex:
Dim r As New Regex("\((.[\*/]?x)\)([\*\+-/])\((.[\*/]?x)\)")
Dim mc As MatchCollection = r.Matches("(3*x)+(2*x)-(4/x)*(2*3x)")
For Each m As Match In mc
    Console.WriteLine("Chaine trouvé: " & m.ToString)
    If m.Groups.Count <> 0 Then
        For i AsInteger = 0 To m.Groups.Count - 1
            Console.WriteLine("Groupe n°" & i & " trouvé dans cette chaine: " & m.Groups(i).ToString)
        Next
     End If
Next

Retourne:
Chaine trouvé: (3*x)+(2*x)
Groupe n°0 trouvé dans cette chaine: (3*x)+(2*x)
Groupe n°1 trouvé dans cette chaine: 3*x
Groupe n°2 trouvé dans cette chaine: +
Groupe n°3 trouvé dans cette chaine: 2*x

On peut encore améliorer l'expression......

Et pour le code:

Au lieu d'appeler deux fois la fonction Matches (Exp.Matches(Expression).Count par exemple) met un objet MatchCollection, sinon elle marche pas vraiment cette fonction; on ne sait pas calculer 3x + 2x, il faut virer les termes x pour calculer ça, et le remettre après, et je vois pas de cast aussi.

A partir de là, soit la fonction récursive n'est pas bonne, soit le regex n'est pas bon, moi je dis que les deux sont à revoir.
Pas le temps d'écrire plus, faut que je dorme..............




Cette discussion est classé dans : net, vb, 2x, expression, littérales


Répondre à ce message

Sujets en rapport avec ce message

Liste qui traduit les expression entre vb6 et vb.net [ par minifranki ] Bonjour,Je suis taner de passer mes journee a essayer dapprendre vb net et s'est toujours sans succes, enfin presque. Je trouve tout plein de tuto sur vb.net Evaluer une expression et avoir le nom d'une variable dans une variable [ par liquide ] bonsoir,Comment coder l'evaluation d'une expression comme on peut le faire avec scriptcontrol en vb.netUn autre probleme se pose, Comment récupérer le matrice echlonnee en vb.net [ par mwanted ] j'ai juste besoin d'echelonner une matrice augmentee  (Gauss ) en VB.net... mais je n'arrive pas a le faire je ne peux pas bien utiliser  les valeurs VB.Net Modifier la dimenssion d'un DataGrid ? [ par MagDix ] Je cherche à savoir si c'est possible de modifier la grosseur d'un DataGrid par l'utilisateur...je chercher et je cherche et je ne trouve pas... enfin CopyMemory VB.NET [ par bouv ] Salut,Je tente de convertir une class de Renfield en .NET, seulement je rencontre des problèmes avec les CopyMemory.J'ai de violents plantages lors de Transfert de fichier [ par vitry94350 ] Bonjour,     Je suis en train de réaliser un agent (vb.net 2008) qui doit permettre le déploiement de logiciel sur des PC distant, j'ai donc rélisé un


Nos sponsors

Sondage...

CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 7,847 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.