Partage
  • Partager sur Facebook
  • Partager sur Twitter

expression bien formée

vérification a l'aide de la structure pile

    10 juin 2021 à 15:10:24

    Bonsoir, besoin d'aide s'il vous plait!

    J'ai écrit un code qui devrait normalement vérifier si une expression est bien formée (les parenthèses ouvrante et fermante sont toutes deux présentes) ou non ( il n'y en a qu'une). Mais dans le cas ou une parenthèse manque ca me renvoie toujours que l'expression est valide, d'où mon problème.😫😫

    Est ce que quelqu'un peut me montrer l'erreur que j'ai commise🙏🙏? Voici mon code:

    #include <stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    #define N 10
    typedef struct pile pile;
    
    struct pile
    {
    	int sommet;
    	char tab[N];
    };
    
    void init(pile p){
    	p.sommet=0;
    }
    
    int P_pleine(pile p){
    	int pleine;
    	if (p.sommet==N)
    	{
    		pleine=1;
    	}
    	else{
    		pleine=0;
    	}
    	return pleine;
    }
    
    int P_vide(pile p){
    	int vide;
    	if (p.sommet==0)
    	{
    		vide=1;
    	}
    	else{
    		vide=0;
    	}
    	return vide;
    }
    
    void empiler(pile p, char x){
    	if (P_pleine(p)==1)
    	{
    		printf("Pile pleine!\n");
    	}
    	else{
    		p.sommet=p.sommet+1;
    		p.tab[p.sommet]=x;
    	}
    }
    
    void depiler(pile p){
    	if (P_vide(p)==1)
    	{
           printf("Pile vide.\n");		
    	}
    	else{
    		p.sommet=p.sommet-1;
    	}
    }
    
    
    
    int parenthese(char* expression){
    	int a,b;
    	pile p;
    	
    	init(p);
    
    	
        for (int i = 0; i < sizeof(expression); i++)
        {
        	if(expression[i]=='(')
        	{
        		empiler(p,expression[i]);
            }
        	else{
        		 if(expression[i]==')'){
        			if (P_vide==0)
        			{
        				depiler(p);
        		    }
        		    else
        		    	a=-1;
        	     }
        	    }
        }
    
    
        if (P_vide(p)==1)
        {
        	a=1;
        }
        else{
        	a=-1;
        }
        return a;
    }
    
    
    void main(){
    	char A[]={"(2+4*2"};
    
        printf("\n\nL'expression ");
      	printf("%s",A);
        printf(" est :\t");
        bienforme(A);
    }
    • Partager sur Facebook
    • Partager sur Twitter
      10 juin 2021 à 15:20:33

      Bonjour,

      J'ai deux grandes remarques :

      • Sur ton code

      Il faut activer les warnings et en prendre compte (chose que j'ai faite avant même de lire ton code) :

      $ gcc -Wall -Wextra -fanalyzer -o par par.c
      par.c: In function ‘init’:
      par.c:14:16: warning: parameter ‘p’ set but not used [-Wunused-but-set-parameter]
         14 | void init(pile p){
            |           ~~~~~^
      par.c: In function ‘parenthese’:
      par.c:72:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
         72 |     for (int i = 0; i < sizeof(expression); i++)
            |                       ^
      par.c:80:27: warning: the comparison will always evaluate as ‘false’ for the address of ‘P_vide’ will never be NULL [-Waddress]
         80 |                 if (P_vide==0)
            |                           ^~
      par.c:66:11: warning: unused variable ‘b’ [-Wunused-variable]
         66 |     int a,b;
            |           ^
      par.c: At top level:
      par.c:102:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
        102 | void main(){
            |      ^~~~
      par.c: In function ‘main’:
      par.c:108:5: warning: implicit declaration of function ‘bienforme’ [-Wimplicit-function-declaration]
        108 |     bienforme(A);
            |     ^~~~~~~~~
      /usr/bin/ld: /tmp/ccC6RnYG.o: in function `main':
      par.c:(.text+0x274): undefined reference to `bienforme'
      collect2: error: ld returned 1 exit status
      

      Il va falloir corriger tout ça.

      N'oublie pas que tous les passages de paramètres se font par copie, donc ta fonction init va modifier une copie de ta pile pas ta pile … il faut revoir le chapitre des pointeurs.

      Il faut écrire bienforme ! on ne va pas le faire à ta place.

      As-tu au moins l'algo avant de vouloir pisser du code ?

      Regarde bien ton cours C, tu devrais y trouver le prototype correct pour main :

      int main(void)
      {
      
         ...
         ton code
         ...
      
      }



      • Sur ta méthode


      Alors utiliser une pile, à moins que cela ne te sois demandé, est un peu overkill. Il suffit d'incrémenter un compteur sur une parenthèse ouvrante et vérifier lors d'une parenthèse fermante s'il y a eu au moins une ouvrante auparavant, si le compteur est à 0 c'est que l'expression est mal formée sinon tu décrémentes et tu continues.

      • Partager sur Facebook
      • Partager sur Twitter
        10 juin 2021 à 15:21:38

        Utilise le debugger et au pas à pas tu vois ce qu'il se passe.

        En tout cas tu passe ta structure en paramètre sans pointeur donc chaque fonction reçoit sa copie de la structure et tu "perds" les changements au niveau de l'appelant.

        • Partager sur Facebook
        • Partager sur Twitter

        git is great because Linus did it, mercurial is better because he didn't.

          10 juin 2021 à 15:44:39

          Il y a place pour de nombreuses simplifications (en plus de ce qui a été dit)
          bool p_pleine(Pile *p) {   // inclure <stdbool.h>
              return p->sommet >= N;
          }
          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            11 juin 2021 à 20:08:48

            White Crow a écrit:

            Bonjour,

            J'ai deux grandes remarques :

            • Sur ton code

            Il faut activer les warnings et en prendre compte (chose que j'ai faite avant même de lire ton code) :

            $ gcc -Wall -Wextra -fanalyzer -o par par.c
            par.c: In function ‘init’:
            par.c:14:16: warning: parameter ‘p’ set but not used [-Wunused-but-set-parameter]
               14 | void init(pile p){
                  |           ~~~~~^
            par.c: In function ‘parenthese’:
            par.c:72:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
               72 |     for (int i = 0; i < sizeof(expression); i++)
                  |                       ^
            par.c:80:27: warning: the comparison will always evaluate as ‘false’ for the address of ‘P_vide’ will never be NULL [-Waddress]
               80 |                 if (P_vide==0)
                  |                           ^~
            par.c:66:11: warning: unused variable ‘b’ [-Wunused-variable]
               66 |     int a,b;
                  |           ^
            par.c: At top level:
            par.c:102:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
              102 | void main(){
                  |      ^~~~
            par.c: In function ‘main’:
            par.c:108:5: warning: implicit declaration of function ‘bienforme’ [-Wimplicit-function-declaration]
              108 |     bienforme(A);
                  |     ^~~~~~~~~
            /usr/bin/ld: /tmp/ccC6RnYG.o: in function `main':
            par.c:(.text+0x274): undefined reference to `bienforme'
            collect2: error: ld returned 1 exit status
            

            Il va falloir corriger tout ça.

            N'oublie pas que tous les passages de paramètres se font par copie, donc ta fonction init va modifier une copie de ta pile pas ta pile … il faut revoir le chapitre des pointeurs.

            Il faut écrire bienforme ! on ne va pas le faire à ta place.

            As-tu au moins l'algo avant de vouloir pisser du code ?

            Regarde bien ton cours C, tu devrais y trouver le prototype correct pour main :

            int main(void)
            {
            
               ...
               ton code
               ...
            
            }



            • Sur ta méthode


            Alors utiliser une pile, à moins que cela ne te sois demandé, est un peu overkill. Il suffit d'incrémenter un compteur sur une parenthèse ouvrante et vérifier lors d'une parenthèse fermante s'il y a eu au moins une ouvrante auparavant, si le compteur est à 0 c'est que l'expression est mal formée sinon tu décrémentes et tu continues.



            • Partager sur Facebook
            • Partager sur Twitter
              11 juin 2021 à 20:36:45

              Est-ce que tu veux valider des choses du genre:
              ()()()() ...
              ((((()))))
              ou si tu veux vérifier plus?

              • Partager sur Facebook
              • Partager sur Twitter

              Le Tout est souvent plus grand que la somme de ses parties.

                11 juin 2021 à 21:54:51

                Racky237 a écrit:

                White Crow a écrit:

                Bonjour,

                blablabla

                Ai-je loupé ta réponse ?

                • Partager sur Facebook
                • Partager sur Twitter
                  12 juin 2021 à 3:35:06

                  Moi aussi, j'ai l'impression d'avoir loupé quelque chose.
                  @White Crow: je ne pense pas que tes remarques étaient méchantes.
                  Si on ignore les warning du compilateur, on s'expose à n'importe quoi.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le Tout est souvent plus grand que la somme de ses parties.

                    13 juin 2021 à 22:36:36

                    @White Crow tu as raison, il me faut relire les pointeurs. C'est là-bas ou tout coince. Et tes remarque ne sont pas méchantes. Je débute en programmation et j'ai voulu directement implémenter l'exercice en C, sans d'abord passer par l'algorithme. Je ne maitrise pas encore assez de choses comme je le pensais, je vais juste aller refaire des recherches.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 juin 2021 à 19:28:42

                      P_vide est une fonction, pour l'appeler

                        if (P_vide==0)


                      il faut peut être (*) lui passer des paramètres ?

                      Les opération empiler et dépiler doivent modifier l'état de la pile. Mais là, ce qui est passé en paramètre c'est une _copie_ de la pile (c'est une différence avec d'autres langages comme Java, PHP, Python, Javascript, ...)

                      (*) sûrement, même.

                      -
                      Edité par michelbillaud 14 juin 2021 à 19:31:58

                      • Partager sur Facebook
                      • Partager sur Twitter

                      expression bien formée

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown