begin process at 2008 05 22 21:42:46
1 177 987 membres
633 nouveaux aujourd'hui
13 991 membres club

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 !

EVALUATION D'UNE FORMULE DANS UNE CHAINE EX:"2+9*51-25/5"


Information sur la source

Catégorie :Maths Classé sous : evaluation, formule, mathematique Niveau : Débutant Date de création : 26/06/2003 Date de mise à jour : 26/06/2003 11:09:52 Vu : 3 081

Note :
5 / 10 - par 1 personne
5,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (9)
Ajouter un commentaire et/ou une note

Description

Cette fonction recoit en paramètre une chaine contenant une formule de math simple (4 opérateurs).. du type : "2+9*51-25/5", et renvoie le résultat (ici 456)...
Pour faire ca, j'isole chaque sous-partie (Nombre, Separateur, Nombre), je la calcule, et la ré-insère dans la formule une fois calulée... puis au suivant.. tant qu'il y a un separateur...

Source

  • Public Function Evaluate(Formule As String) As Double
  • Dim PosCour, PosSep, PosAV, PosAP, Av, Ap, Res
  • Dim Separateurs(3), NumSep, Formule2
  • 'liste des separateurs
  • Separateurs(0) = "/"
  • Separateurs(1) = "*"
  • Separateurs(2) = "+"
  • Separateurs(3) = "-"
  • For NumSep = 0 To 3
  • PosSep = InStr(1, Formule, Separateurs(NumSep))
  • While PosSep > 0
  • 'on determine le nombre AVANT le separateur
  • PosCour = PosSep - 1
  • While (IsNumeric(Mid(Formule, PosCour, 1)))
  • PosCour = PosCour - 1
  • If PosCour = 0 Then GoTo suite:
  • Wend
  • suite:
  • PosAV = PosCour + 1
  • Av = Mid(Formule, PosAV, PosSep - PosAV)
  • 'on determine le nombre APRES le separateur
  • PosCour = PosSep + 1
  • While IsNumeric(Mid(Formule, PosCour, 1))
  • PosCour = PosCour + 1
  • Wend
  • PosAP = PosCour
  • Ap = Mid(Formule, PosSep + 1, PosAP - PosSep - 1)
  • 'On calcule la sous-partie isolée
  • Select Case NumSep
  • Case 0: '/
  • Res = Val(Av) / Val(Ap)
  • Case 1: '*
  • Res = Val(Av) * Val(Ap)
  • Case 2: '+
  • Res = Val(Av) + Val(Ap)
  • Case 3: '-
  • Res = Val(Av) - Val(Ap)
  • End Select
  • 'on réécrit la formule avec la sous-partie calculée
  • Formule = Left(Formule, PosAV - 1) & Trim(Str(Res)) & Mid(Formule, PosAP)
  • PosSep = InStr(1, Formule, Separateurs(NumSep))
  • Wend
  • Next
  • Evaluate = Val(Formule)
  • End Function
Public Function Evaluate(Formule As String) As Double

    Dim PosCour, PosSep, PosAV, PosAP, Av, Ap, Res
    Dim Separateurs(3), NumSep, Formule2
    
    'liste des separateurs
    
    Separateurs(0) = "/"
    Separateurs(1) = "*"
    Separateurs(2) = "+"
    Separateurs(3) = "-"

    For NumSep = 0 To 3
        
        PosSep = InStr(1, Formule, Separateurs(NumSep))
        While PosSep > 0
            'on determine le nombre AVANT le separateur
            PosCour = PosSep - 1
            While (IsNumeric(Mid(Formule, PosCour, 1)))
                PosCour = PosCour - 1
                If PosCour = 0 Then GoTo suite:
            Wend
suite:
            PosAV = PosCour + 1
            Av = Mid(Formule, PosAV, PosSep - PosAV)
            'on determine le nombre APRES le separateur
            PosCour = PosSep + 1
            While IsNumeric(Mid(Formule, PosCour, 1))
                PosCour = PosCour + 1
            Wend
            PosAP = PosCour
            Ap = Mid(Formule, PosSep + 1, PosAP - PosSep - 1)
            
            'On calcule la sous-partie isolée
            Select Case NumSep
                Case 0: '/
                    Res = Val(Av) / Val(Ap)
                Case 1: '*
                    Res = Val(Av) * Val(Ap)
                Case 2:  '+
                    Res = Val(Av) + Val(Ap)
                Case 3:  '-
                    Res = Val(Av) - Val(Ap)
            End Select
            
            'on réécrit la formule avec la sous-partie calculée
            Formule = Left(Formule, PosAV - 1) & Trim(Str(Res)) & Mid(Formule, PosAP)
            PosSep = InStr(1, Formule, Separateurs(NumSep))
        Wend
    Next
    Evaluate = Val(Formule)
End Function

Conclusion

Bon, le code est pas parfait, loin de là, mais c'est l'algo qui compte non... ;)
N'hésitez pas a m'insulter parceque je gère pas les erreurs, j'utilise un goto, et parce que je gère pas les parenthèses aussi...
m'enfin voilà koi... si vous pouvez le completer, n'hezitez pas...
Merci à DoDoDODo ;p
  • signaler à un administrateur
    Commentaire de Saros le 26/06/2003 14:23:15

    Pourquoi ne pas mettre puissance ? C'est aussi un opérateur binairee de base...
    De plus il traite mal la chaine : 25*2/4 = 0.5 ???
    Il y a pas mal de choses à corriger.

  • signaler à un administrateur
    Commentaire de orisa le 26/06/2003 15:37:51

    Oui pour moi non plus ça ne marche pas. en plus dès qu'il y a des virgules le résultat passe du marant au navrant, mais c'est pas grave, persévère !

  • signaler à un administrateur
    Commentaire de EBArtSoft le 26/06/2003 16:54:50 administrateur CS

    regarde les sources suivantes :
    http://www.vbfrance.com/article.aspx?Val=3728
    http://www.vbfrance.com/article.aspx?Val=7310

    by@

  • signaler à un administrateur
    Commentaire de squalyl le 30/06/2003 18:44:31

    Il faut gérer la priorité des opérations dans 3 boucles séparées: une pour les quotients, une pour les produits et une pour les sommes/différences. J'ai fait ca en info cet année, à part que c'était en C, mais l'algo est le même.

    En plus cet algo n'a d'intérêt que s'il gère les parenthèses et les sin/cos/tan/exp/log/sqrt/etc..., ce qui est autrement plus difficile. Bon quand l'un est fait, ils sont tous faits.

    Et t'as oublié de sortir une erreur dans les cas où:
    - tu divises par zéro;
    - t'as deux opérateurs qui se suivent.

    Finalement si on met un espace dans ta chaine, c'est mort.

    Note: la TI89/92+ ne gère pas ca direct.
    2+9*51-25/5

    devient:
    "5 25 / 51 9 * - 2 +"

    soit:
    [ [ [5 25]/ [51 9]* ]- 2]+
    ou []x représente l'opération x appliquée aux deux args précédents.
    Les priorités ne posent plus de pb.
    Il suffit alors de parser ta formule (parenthèses comprises) pour aboutir à cette forme[chiant] puis de calculer le résultat numérique [facile].

  • signaler à un administrateur
    Commentaire de Saros le 30/06/2003 21:25:58

    Le mieux est de convertir la chaîne en RPN (ce que tu disais avec les TI 89/92(II)(+))... Et là c'est encore autrement plus dur.
    À propos, les quotients etles divisions ont la même priorité, non ? Alors pourquoi faire quotient PUIS multiplication PUIS addtion (soustraction) ?

  • signaler à un administrateur
    Commentaire de revivall le 30/06/2003 22:17:49

    la méthode optimale est je pense de faire une analyse lexicale avec génération d'automate à état fini déterministe puis le transformer en algo
    c ce que fait vb ou tt autre langage de programmation pour lire le code source
    mais j'ai pas dit que c simple, loin de là ... ;)

  • signaler à un administrateur
    Commentaire de squalyl le 01/07/2003 00:49:19

    >À propos, les quotients etles divisions ont la même priorité, non ?

    Tu peux me dire la différence que tu trouves entre les 2?

    Allez,un indice: au lieu d'un automate, tu mets une fonction récursive qui s'apelle quand elle trouve des parenthèses à traiter...

  • signaler à un administrateur
    Commentaire de Saros le 01/07/2003 13:52:28

    >Tu peux me dire la différence que tu trouves entre les 2?

    Non justement il n'y en a pas (x / y = x * (y ^ -1)) mais tu dis qu'il faut une boucle pour les quotients et une autre pour les multiplications...

  • signaler à un administrateur
    Commentaire de k_wa le 05/04/2005 13:02:32

    tu inséère le composant control script
    et tu tape result=controlscript1.eval("5+3*2/9-2")
    ce contrôle fonctionne très bien et n'a pas besoin d'être réinventé...

Ajouter un commentaire

Appels d'offres

Pub



Snippets en rapport

CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Téléchargements

Boutique

Boutique de goodies CodeS-SourceS