IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Corriger/améliorer mon code de calculatrice en PHP pour qu'il traite les calculs les plus complexe


Sujet :

Langage PHP

  1. #1
    Membre très actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2013
    Messages
    453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 453
    Par défaut Corriger/améliorer mon code de calculatrice en PHP pour qu'il traite les calculs les plus complexe
    Bonsoir.

    J'essaie de faire une calculatrice en PHP à partir des données entrées depuis un champs input. C'est-à-dire que je souhaiterais vérifier si ce qui est entré via le champs du formulaire HTML est un calcul, que cela procède au calcul demandé via le champs du formulaire en Action.

    Voici mon Code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    if (stripos($term, '+') !== false) {
    			$termArray = explode("+", $term);
    			if (is_numeric($termArray[0]) && is_numeric($termArray[2])) {
    					$calcResult = $termArray[0] + $termArray[2];
    			} else if (is_numeric($termArray[0]) && is_numeric($termArray[4])) {
    					$calcResult = $termArray[0] + $termArray[4];
    			}
    		} elseif (stripos($term, '-') !== false) {
    			$termArray = explode("-", $term);
    			if (is_numeric($termArray[0]) && is_numeric($termArray[2])) {
    					$calcResult = $termArray[0] - $termArray[2];
    			} else if (is_numeric($termArray[0]) && is_numeric($termArray[4])) {
    					$calcResult = $termArray[0] - $termArray[4];
    			}
    		} elseif (stripos($term, '*') !== false) {
    			$termArray = explode("*", $term);
    			if (is_numeric($termArray[0]) && is_numeric($termArray[2])) {
    					$calcResult = $termArray[0] * $termArray[2];
    			} else if (is_numeric($termArray[0]) && is_numeric($termArray[4])) {
    					$calcResult = $termArray[0] * $termArray[4];
    			}
    		} elseif (stripos($term, 'x') !== false) {
    			$termArray = explode("x", $term);
    			if (is_numeric($termArray[0]) && is_numeric($termArray[2])) {
    					$calcResult = $termArray[0] * $termArray[2];
    			} else if (is_numeric($termArray[0]) && is_numeric($termArray[4])) {
    					$calcResult = $termArray[0] * $termArray[4];
    			}
    		} elseif (stripos($term, '/') !== false) {
    			$termArray = explode("/", $term);
    			if (is_numeric($termArray[0]) && is_numeric($termArray[2])) {
    					$calcResult = $termArray[0] / $termArray[2];
    			} else if (is_numeric($termArray[0]) && is_numeric($termArray[4])) {
    					$calcResult = $termArray[0] / $termArray[4];
    			}
    		}
    Mon problème, c'est que je suis perdu dans mon propre code. Je me demande en fait, si l'utilisateur cherchait à faire un calcul un peu plus complexe comme par exemple: 5+5-2+20/3 ???

    Comment modifier mon code pour qu'il réponde à de tel calcul complexe sachant que ce que moi j'ai essayé de faire dans mon code ci-dessus, est d'abord de vérifier si ce qui est entré dans l'input est contient à chaque fois un signe +, -, *, x, ou encore /. Si oui, je convertis en un tableau via la fonction PHP explode l'entrée représentée par la variable $term séparée à chaque fois par le signe arithmétique (+, -, *, x, ou /) trouvé dans l'entrée et je procède au calcul de chaque valeur du tableau départagé. De deux, je n'ai réussi à traiter que deux (2) à calculer à chaque fois.

    Mais je sens qu'il y a mieux à faire et ce que j'ai fait ne peut rien résoudre des calcul complexe dans le cas où l'entrée du formulaire input serait par exemple un truc du genre: (78/2-)*12+5.

    Aidez-moi s'il vous plaît à modifier mon code afin de l'adapter au traitement des calcul les plus complexe.

  2. #2
    Membre émérite Avatar de ypcman
    Homme Profil pro
    Retraité codeur !
    Inscrit en
    Janvier 2011
    Messages
    601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Retraité codeur !
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2011
    Messages : 601
    Par défaut
    Problème bien connu ...
    Tu dois commencer par isoler chaque terme dans un tableau sachant qu'il y a trois types de terme : les nombres, les 4 opérateurs (plus modulo, plus puissance, plus ...) et les 2 parenthèses.
    Ensuite, tu dois calculer d'abord toutes les opérations entre parenthèses en commençant par celle de plus bas niveau. Cad tu cherches la 1° ) fermante puis tu remontes à la ( juste precécedente et tu calcule ce qui est à l'intérieur pour pouvoir supprimer les 2 (). Tu reproduis cette recherche de ) jusqu'à supprimer toutes les ().
    Pour les calculs, attention à la priorité des opérateurs les uns par rapport aux autres : 1+3*2 c'est 1+(3×2) et pas (1+3)×2 ...Tu dois donc calculer les / et × avant les + et -
    Voilà, voilà quelques pistes. Bon courage !

  3. #3
    Membre très actif
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2013
    Messages
    453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2013
    Messages : 453
    Par défaut
    Merci beaucoup pour la réponse.

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    Voici une manière (la manière basique) de résoudre ce genre de problème et ce, quelque soit le langage utilisé. Pour celà on utilise une pile (une structure de données LIFO (Last In First Out), qu'on peut simuler avec un tableau en PHP) et deux boucles imbriquées.
    1. On tokenize la chaîne: c'est à dire qu'on la découpe en éléments atomiques (en nombres, opérateurs, parenthèses).
    2. On parcourt la liste de token obtenue dans une boucle et on les place dans une pile. À chaque tour de cette boucle principale, une deuxième boucle effectue des calcules lorsque c'est possible:
      • lorsque les trois derniers élément de la pile sont un opérande, un opérateur et un autre opérande, on les dépiles et on empile le résultat de l'opération si et seulement si le token suivant le permet (priorité des opérateurs: c'est le cas si ce qui suit est un signe plus ou un signe moins, une parenthèse fermante ou la fin du tableau de token.) ou si l'opérateur à une priorité haute comme la multiplication ou la division. Lorsque les trois derniers tokens sont un nombre entre parenthèses, on les dépile et on empile le nombre (quelque soit le token suivant).
      • lorsque le token suivant ne permet pas d'effectuer une opération, on continue à empiler jusqu'à ce qu'un calcul soit possible.
    3. À l'issue de cette boucle principale, la pile ne doit contenir qu'un seul élément (un nombre) qui sera le résultat de l'expression. Si ce n'est pas le cas, alors la syntaxe de l'expression entrée est incorrecte.


    Même si PHP dispose de structures de données plus adaptées (les data structures), je te conseille dans un premier temps d'utiliser un tableau pour faire la pile.

    Voici le déroulement de cet algorithme:

    Prenons pas exemple l'expression: 1+1+(6/2)*(12-6*(4-3))


    En pseudo code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $tokens = ['1', '+', '1', '+', '(', '6', '/', '2', ')', '*', '(', '12', '-', '6', '*', '(', '4', '-', '3', ')', ')'];
    $stack = []; // la pile
     
    foreach ($tokens as $token) {
        // empile le token
        while ("tant que les trois derniers tokens de la pile sont calculables") {
            // calcule
            // dépile les trois derniers tokens
            // empile le résultat
        }
    }
    Déroulement de l'algorithme:
    Code txt : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    contenu de la pile             tokens    commentaires    
    -----------------------------+---------+-----------------------------------------------------------------------
                                 |    1    | la pile est vide: on empile le 1er token
    1                            |    +    |
    1 +                          |    1    |
    1 + 1                        |    +    | 2 opérandes, un opérateur, le token suivant est +, donc on effectue.
    .............................°.........°.......................................................................
                                 :    +    : on dépile les 2 opérandes et l'opérateur (boucle secondaire)
    2                            :    +    : on empile le résultat. pas d'autre opération possible, token suivant
    .............................°.........°.......................................................................
    2 +                          |    (    | on ne peut rien calculer, on continue d'empiler
    2 + (                        |    6    | idem
    2 + ( 6                      |    /    |
    2 + ( 6 /                    |    2    |
    2 + ( 6 / 2                  |    )    | parenthèse fermante, on effectue
    .............................°.........°.......................................................................
    2 + (                        :    )    : on dépile
    2 + ( 3                      :    )    :
    .............................°.........°.......................................................................
    2 + ( 3 )                    |    *    | un nombre entouré de parenthèse, on dépile
    .............................°.........°.......................................................................
    2 +                          :    *    :
    2 + 3                        :    *    : on empile le nombre. Le * suivant ne permet pas d'effectuer 2 + 3
    .............................°.........°.......................................................................
    2 + 3 *                      |    (    |
    2 + 3 * (                    |    12   |
    2 + 3 * ( 12                 |    -    |
    2 + 3 * ( 12 -               |    6    |
    2 + 3 * ( 12 - 6             |    *    | Le token suivant étant *, on ne peut pas effectuer 12 - 6
    2 + 3 * ( 12 - 6 *           |    (    |
    2 + 3 * ( 12 - 6 * (         |    4    |
    2 + 3 * ( 12 - 6 * ( 4       |    -    |
    2 + 3 * ( 12 - 6 * ( 4 -     |    3    |
    2 + 3 * ( 12 - 6 * ( 4 - 3   |    )    |
    .............................°.........°.......................................................................
    2 + 3 * ( 12 - 6 * (         :    )    :
    2 + 3 * ( 12 - 6 * ( 1       :    )    :
    .............................°.........°.......................................................................
    2 + 3 * ( 12 - 6 * ( 1 )     |    )    |
    .............................°.........°.......................................................................
    2 + 3 * ( 12 - 6 *           :    )    :
    2 + 3 * ( 12 - 6 * 1         :    )    :
    2 + 3 * ( 12 -               :    )    :
    2 + 3 * ( 12 - 6             :    )    :
    2 + 3 * (                    :    )    :
    2 + 3 * ( 6                  :    )    :
    .............................°.........°.......................................................................
    2 + 3 * ( 6 )                |         | fin des tokens (dernier tour de la boucle principale)
    .............................°.........°.......................................................................
    2 + 3 *                      :         :
    2 + 3 * 6                    :         :
    2 +                          :         :
    2 + 18                       :         :
                                 :         :
    20                           :         :
    -----------------------------+---------+-----------------------------------------------------------------------

    (Les lignes contenant : correspondent aux passages dans la deuxième boucle.)

    Lorsque tu auras implémenté ça et que tu l'auras posté, je te dirais comment faire la même chose en trois lignes.

    NB: comme tout algorithme basé sur les boucles, il est possible d'en faire une variante utilisant une fonction récursive (et vice versa).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. améliorer mon code avec une boucle
    Par hotdogFRANCE dans le forum C#
    Réponses: 4
    Dernier message: 29/01/2011, 17h35
  2. Votre avis pour améliorer mon code (opérations matricielles)
    Par Schopenhauer dans le forum Débuter
    Réponses: 42
    Dernier message: 17/09/2010, 19h25
  3. [WD15] Comment améliorer mon code LanceAppli
    Par papydev dans le forum WinDev
    Réponses: 13
    Dernier message: 20/08/2010, 12h17
  4. Réponses: 1
    Dernier message: 21/11/2007, 09h04
  5. [Sécurité] Comment amélioré mon code ?
    Par Nadd dans le forum Langage
    Réponses: 14
    Dernier message: 03/03/2006, 20h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo