Vérificateur d'expressions mathématique

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Vérificateur d'expressions mathématique

Message par Shadow »

Salut,

J'ai réalisé un Vérificateur d'expressions mathématique et c'est pas facile :(
Pour le moment je me contente déjà des 4 opérateurs de base + les parenthèses et les nombre à virgules et rien que ça déjà c'est la jungle !
Il est très permissif sur les espace car il ne les prends pas en compte et c'est fais exprès.

Evidement c'est pas très optimisé mais ça m'a l'air de fonctionné.

Pour l'évaluateur d'expressions mathématique avec résultat et tous, c'est pas moi qui l'ai fais par contre, c'est L'IA :mrgreen:
Faux que je me ménage moi aussi, jvé cramé tous mes pauvres neurones !

Evaluateur d'expressions mathématique dans un autre sujet ! :)

Code : Tout sélectionner

; Fonction pour valider une chaîne représentant une expression mathématique.
Procedure.s CheckMathExpression(Expression$)
  
  ; Si l'expression est vide ou ne contient que des espaces.
  If Expression$ = "" Or ReplaceString(Expression$, Chr(32), "") = ""
    ProcedureReturn "Erreur: L'expression est vide."
  
  Else
    
    ; Initialisation des variables nécessaires à la validation.
    ParenthesesCount.i = 0 ; Compteur pour suivre l'équilibre des parenthèses ouvrantes et fermantes.
    LastChar.s = ""       ; Précédent caractère significatif analysé.
    PositionLastChar.i = 0 ; Position du précédent caractère significatif.
    CurrentChar.s = ""     ; Caractère actuellement analysé.
    NombreVirgule.b = #False ; Indicateur de la gestion des virgules dans un nombre décimal.
    
    ExpressionLength.i = Len(Expression$) ; Longueur totale de l'expression.
    
    ; Parcourir chaque caractère de l'expression.
    For IndexExpression.i = 1 To ExpressionLength.i
      
      ; Extraire le caractère actuel.
      CurrentChar.s = Mid(Expression$, IndexExpression.i, 1)
      
      ; Vérifier que le caractère est autorisé.
      If Not FindString("0123456789+-*/(), ", CurrentChar.s)
        ProcedureReturn "Erreur: Caractère non autorisé '" + CurrentChar.s + "' à la position " + Str(IndexExpression.i) + "."
      EndIf
      
      ; Gestion des parenthèses ouvrantes.
      If CurrentChar.s = "("
        
        ; Vérification: une parenthèse ouvrante ne peut pas suivre une virgule.
        If LastChar.s = ","
          ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
        EndIf
        
        ParenthesesCount.i + 1 ; Incrémenter le compteur de parenthèses ouvrantes.
        
        ; Réinitialiser le suivi des virgules.
        If NombreVirgule.b = #True
          NombreVirgule.b = #False
        EndIf
      
      ; Gestion des parenthèses fermantes.
      ElseIf CurrentChar.s = ")"
        
        ; Vérification: parenthèse fermante inattendue.
        If ParenthesesCount.i <= 0
          ProcedureReturn "Erreur: Parenthèse fermante inattendue à la position " + Str(IndexExpression.i) + "."
        Else
          
          ParenthesesCount.i -1 ; Décrémenter le compteur de parenthèses.
          
          ; Vérifications contextuelles pour la parenthèse fermante.
          If LastChar.s = "+" Or LastChar.s = "-" Or LastChar.s = "*" Or LastChar.s = "/"
            ProcedureReturn "Erreur: Opérateur invalide à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
          ElseIf LastChar.s = ","
            ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
          ElseIf LastChar.s = "("
            ProcedureReturn "Erreur: Parenthèse vide à la position " + Str(IndexExpression.i) + "."
          EndIf
        EndIf
        
        ; Réinitialiser le suivi des virgules.
        If NombreVirgule.b = #True
          NombreVirgule.b = #False
        EndIf
        
      ; Gestion des chiffres
      ElseIf (CurrentChar.s >= "0" And CurrentChar.s <= "9")
        
        ; Vérification: un chiffre ne peut pas suivre une parenthèse fermante.
        If LastChar.s = ")"
          ProcedureReturn "Erreur: Parenthèse fermante invalide à la position " + Str(PositionLastChar.i)
        EndIf
        
      ; Gestion des opérateurs (+, -, *, /)
      ElseIf CurrentChar.s = "+" Or CurrentChar.s = "-" Or CurrentChar.s = "*" Or CurrentChar.s = "/"
        
        ; Réinitialiser le suivi des virgules après un opérateur.
        If NombreVirgule.b = #True
          NombreVirgule.b = #False
        EndIf
        
        ; Vérification: un opérateur ne peut pas suivre un autre opérateur ou être isolé, sauf cas particulié pour l'oppérateur "-".
        ; Exemples qui fonctionne: 45 - -12 | 21 + -36 |  67 * -91 | 37 / -29.
        
        ; Si le précédent caractère n'est pas un chiffre, sinon c'est bon.
        If (LastChar.s < "0" Or LastChar.s > "9")
          Select CurrentChar.s
            Case "+", "*", "/" ; Le caracère actuel est un Oppérateur autre que "-".
              If LastChar.s = "+" Or LastChar.s = "-" Or LastChar.s = "*" Or LastChar.s = "/" Or LastChar.s = "(" Or LastChar.s = "" ; Si le précédent caractère n'est pas un Oppérateur ni "(", ni rien.
                ProcedureReturn "Erreur: Opérateur invalide à la position " + Str(IndexExpression.i) + ": " + CurrentChar.s
              EndIf
            Case "-" ; Le caracère actuel est "-", cas spécial ici.
              If LastChar.s = ","
                ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
              EndIf
            Default
          EndSelect
          If LastChar.s = "," ; Si le précédent caractère est une virgule.
            ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
          EndIf
        EndIf
        
      ; Gestion des virgules.
      ElseIf CurrentChar.s = ","
        
        ; Vérification: une virgule ne peut pas suivre une autre virgule.
        If LastChar.s = ","
          ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
        ; Vérification: une virgule doit suivre un chiffre.
        ElseIf (LastChar.s < "0" Or LastChar.s > "9")
          ProcedureReturn "Erreur: Virgule invalide à la position " + Str(IndexExpression.i) + "."
        EndIf
        
        ; Mettre à jour le suivi des virgules.
        If NombreVirgule.b = #False
          NombreVirgule.b = #True
        Else
          ProcedureReturn "Erreur: Virgule invalide à la position " + Str(IndexExpression.i) + "."
        EndIf
        
      ; Ignorer les espaces.
      ElseIf CurrentChar.s = " "
        Continue
      EndIf
      
      ; Mise à jour des informations sur le précédent caractère significatif.
      If CurrentChar.s <> Chr(32)
        LastChar.s = CurrentChar.s
        PositionLastChar.i = IndexExpression.i
      EndIf
      
    Next
    
    ; Vérification finale après la fin de la boucle.
    If LastChar.s = "+" Or LastChar.s = "-" Or LastChar.s = "*" Or LastChar.s = "/"
      ProcedureReturn "Erreur: Opérateur invalide à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
    ElseIf LastChar.s = "("
      ProcedureReturn "Erreur: Parenthèse ouvrante invalide à la position " + Str(PositionLastChar.i) + "."
    ElseIf ((LastChar.s < "0" Or LastChar.s > "9") And LastChar.s <> ")")
      ProcedureReturn "Erreur: Caractère invalide à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
    EndIf
    
    ; Vérification de l'équilibre des parenthèses.
    If ParenthesesCount.i <> 0
      ProcedureReturn "Erreur: Parenthèse fermante manquante à la position " + Str(IndexExpression.i) + "."
    EndIf
  
  EndIf
  
  ; Si aucune erreur n'a été détectée, retourner "Pas d'erreur".
  ProcedureReturn "Pas d'erreur."
  
EndProcedure


; Exemple d'utilisation et tests supplémentaires :
Expression.s = " , -  1 , 1  / " ; Résultat attendu : Erreur: Virgule invalide à la position 2.
Debug "Expression 1 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " - / , * +  8 9 *  1 0 + 2  5 " ; Résultat attendu : Erreur: Opérateur invalide à la position 4: /.
Debug "Expression 2 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " / 8 - 3 * 1  4 , 2 1 /  1 , " ; Résultat attendu : Erreur: Opérateur invalide à la position 2: /.
Debug "Expression 3 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " 1  /   -  +  / -  1 0 4 + " ; Résultat attendu : Erreur: Opérateur invalide à la position 12: +.
Debug "Expression 4 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " 25 * 248 + ( ( ( 200 " ; Résultat attendu : Erreur: Parenthèse fermante manquante à la position 23.
Debug "Expression 5 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " , 147  + , 9 (50,25 * " ; Résultat attendu : Erreur: Virgule invalide à la position 2.
Debug "Expression 6 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " (6,5 - 4,256 / 65,03258) , 8 ) 89 " ; Résultat attendu : Erreur: Virgule invalide à la position 27.
Debug "Expression 7 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " * / 56 -   / + 452 )) / ( " ; Résultat attendu : Erreur: Opérateur invalide à la position 2: *.
Debug "Expression 8 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " 3,75741 + 2,5)) * ((10,75 " ; Résultat attendu : Erreur: Parenthèse fermante inattendue à la position 15.
Debug "Expression 9 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " + 5,987654 - 458,25461 " ; Résultat attendu : Erreur: Opérateur invalide à la position 2: +.
Debug "Expression 10 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " ) / (7,25 - 3,0123428965)))  ,  " ; Résultat attendu : Erreur: Parenthèse fermante inattendue à la position 2.
Debug "Expression 11 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " 4 5 * ( 5 8 - 5 6 ) / 2 5 - - 3 5 + - 4 5 " ; Résultat attendu : Pas d'erreur.
Debug "Expression 12 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " - 4,7 - 9,1  /  -  10 + 25 / 8 - 3 * 14,21 / 1,1 / - 18 " ; Résultat attendu : Pas d'erreur.
Debug "Expression 13 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " 78 *-47,598 (, 4 ) " ; Résultat attendu : Erreur: Virgule invalide à la position 15.
Debug "Expression 14 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = " - 4,     7  - 9, 1  /  -   10 + 25 / 8 - 3 * 14,21 /  1,1  /   -     -  10 4 + 25 * 248 + (((200,147  + (50,25 * (6,5 - 4,256 / 65,03258)  *  89 *  56 -     452 )) / (3,75741 + 2,5)) * ((10,75 + 5,987654 - 458,25461) / (7,25 - 3,0123428965)))    -     - 47  " ; Résultat attendu : Pas d'erreur.
Debug "Expression 15 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = "(1 + (2 * (3 - (4 / (5 + (6 - (7 * (8 / (9 - (10))))))))))" ; Résultat attendu : Pas d'erreur.
Debug "Expression 16 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = "1 + 2 - 3 * 4 / 5 + 6 - 7 * 8 / 9 + 10 - 11 * 12 / 13 + 14" ; Résultat attendu : Pas d'erreur.
Debug "Expression 17 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = "1 + - + -2" ; Résultat attendu : Erreur: Opérateur invalide à la position 7: +.
Debug "Expression 18 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = "((1 + 2) * (3 - (4 / 5)))" ; Résultat attendu : Pas d'erreur.
Debug "Expression 19 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"

Expression.s = "((1 + 2) * (3 - (4 / 5)" ; Résultat attendu : Erreur: Parenthèse fermante manquante à la position 24.
Debug "Expression 20 = " + Chr(34) + Expression.s + Chr(34) + ", Résultat = " + CheckMathExpression(Expression.s)
Debug "-----"
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.