Générer une chaine correctement parenthésée

Résolu/Fermé
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 - Modifié le 5 oct. 2022 à 15:39
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 - 5 oct. 2022 à 18:23

Bonjour,

On m'a donné cet algorithme et on me demande de le traduire en C, sauf que c'est un peu difficile :

 
 p = PileVide()

   tant que non Vide(p) 
      choisir entre:
      { c est une parenthèse ouvrante }
	  c = parenthèse ouvrante
	  Empiler(p , c)
       c est une parenthèse fermante }
	  si non Vide(p) alors
	     c = parenthèse fermante correspondant à Sommet(p)
             Dépiler(p)
      { c est un caractère peu importe}
	  c = caractère qui n'a pas de parenthése
      afficher c

... dans lequel :

  • PileVide est une fonction qui crée une pile vide ;
  • Vide est une fonction qui renvoie true si et seulement si la pile est vide.

Voici par exemple des résultats valides :

(a(bvcbn))
(aevvjbb(er(yhh)))

Je ne sais pas si l'algorithme qu'on m'a donné est complet, car je ne vois pas comment il peut de générer une chaîne bien parenthésée.

Voici mes idées :

  • Pour l'histoire de choisir, ça me rappelle switch(..) en C
  • Pour générer un texte aléatoirement je crois qu'on peut faire :
char chaine = "abcdefghijklmnopqrstuvwxyz";
char chaine aleatoire[26] = " ";
chaine aletatoire = chaine[rand() % 26];

25 réponses

Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:25
typedef enum {
  Ouvrante,
  Fermante,
  Quelconque
} caractere;

?

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
30 sept. 2022 à 16:50

en fait il faut que la fonction renvoie par exemple (a(bvcbn)) ou (aevvjbb(er(yhh))) .Il doit générer un texte bien parenthésé de façon aléatoire

0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
Modifié le 1 oct. 2022 à 08:57

Soit.

Mais.

Par exemple, ce texte

on suppose que il existe une fonctioon appelée Pilevide qui vide crée une pile vide et  vide qui renvoie un bool ,si true alors la pile est vide sinon elle ne l'est pas

Et ces morceaux d'algorithme

 p = PileVide()

   tant que non Vide(p)
   '...
   Empiler(p , c)
   '...
   Dépiler(p)

p est donc un bool, donc

  • il ne peut pas être vide, un bool c'est true ou false, jamais vide,
  • on ne peut pas non plus l'empiler ou le dépiler.
     

Et puis, après vérification dans plusieurs dictionnaires, l'adjectif (ou le participe passé) "parenthésé" n'existe pas, algorithme est masculin, comme te l'a fait remarquer Phil (que je salue).


Bref, entre ce qu'on doit deviner de ton texte et l'algorithme, rien n'est cohérent.


0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:01

Ah mon truc est marqué resolu mais non

ah bon ce mot n'existe pas,pourtant dans mon énoncé ils ont ecrit bien parenthésé ...

J'ai pas fait attention a ces erreurs de frappe

je voulais dire Pilevide est une fonction qui crée une pilevide et Vide(p) est une fonction qui verifie si une pile est vide ou pas.Si elle l'est,elle renvoie true sinon false


 

j'ai essayé d'ecrire ceci mais rien ne se passe lorsque j'essaye de tester

char generer_parenthese_ouvrante(int n){
  if (n == 0)
    return '(';
  else if (n == 1)
    return '[';
  else
    return '{';
}

char generer_parenthese_fermante(int n){
  if (n == 0)
    return ')';
  else if (n==1)
    return ']';
  else
    return '}';
}

void generer_texte_bien_parenthese(){
  char chaine[26] = "abcdefghijklmnopqrstuvwxyz";
  PileCaractere p = creer_pile(&p);
  char c;
  int n;
  
  while(!est_vide(&p) ){
    printf("Valeur de n:");
    scanf("%d\n", &n) ;
    printf("Valeur de c:");
    scanf(" %c", &c);
    switch (c) {
    case Ouvrante:
      c = generer_parenthese_ouvrante(n);
      empiler(&p,c);
      break;
    case Fermante:
      c = generer_parenthese_fermante(n);
      if(!est_vide(&p) )
        c = sommet(&p);        
      break;
    case Quelconque:
      c = chaine[rand() % 26];
      break;
   }
 }
 printf("%c", c);
}

0
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 9
2 oct. 2022 à 14:33

Bonjour,
Les variables Ouvrante, Fermante et Quelconque ne sont pas initialisées (ton compilateur devrait t'en avoir touché un mot à ce propos d'ailleurs).

Sinon je rejoins les commentaires précédents à propos de la clarté de l'ensemble de tes propos :
1) traduire un algo en C : ok.
mais...
sois plus clair concernant l'énoncé : ce que tu as (point de départ), ce que tu dois faire (consigne).

 

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
2 oct. 2022 à 14:42

en fait je sais pas comment dans le cas de case initialiser des trucs comme ça

peut etre dois etre char Ouvrante,Fermante,Quelconque

ou peut etre créer un type énuéré typdef enum{Ouvrante,Fermante,Quelconque}

Pourtant j'ai expliqué,j'ai dit que je dois traduire en C l'algorithme qu'on m'a donné pour qu'il génére un texte avec le bon nombre de parenthése ouvrante et fermante

Ex:(ab(cd)) ou ( { gh) }

0
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 9
2 oct. 2022 à 14:59

Donc l'idée ce serait juste de générer le bon nombre de parenthèses?
Je vais prendre l'exemple d'une équation de mathématiques pour simplifier les choses:
[cas 1] : a(b+2(4-2)+2(6-4)) <-- valide
[cas 2] : a(b+2(4-2)+2(6-4) <-- invalide (il manque une parenthèse)
[cas 3] : a)b+2(4-2)+2(6-4)( <-- invalide (sens des parenthèses)

Il te faut donc traiter les 3 cas de figure ci-dessus.
Le plus simple : procéder via 2 variables, p_ouvrante et p_fermante par exemple, toutes deux initialisées à 0. Elles vont comptabiliser le nombre de parenthèses ouvrantes et fermantes.
règle : tu incrémentes le nombre de parenthèses à chaque fois que tu rencontres ces parenthèses (ou bien lorsque tu les génères).
cas 3 : règle importante → il te faut toujours au moins plus de parenthèses ouvrantes que fermantes, sinon il y a une faute quelque part. Illustration : a = 5(3))+2.
En bout de course : il te faut autant de parenthèses ouvrantes et fermantes.

Ce qui n'est pas clair dans ton énoncé, c'est la façon de procéder :
- insertion d'une parenthèse dans le texte, ou bien remplacement d'un caractère de la chaîne une parenthèse?
- placement +/-aléatoire des parenthèses?
Est-ce que ça t'éclaire un peu?

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
2 oct. 2022 à 14:48

cet algorithme n'est pas déterministe,il y a 2 choix à faire A chaque pas de l'itération  ,

-dois t-on encore afficher d'autres caractéres ou bien s'arreter?

-si on continue,quesce que tu dois afficher

Ces choix ne sont pas dit dans l'algorithme donc :

-Tu dois dire dans ton code quel choix tu as fait pour générer une chaine bien parenthésé (bon dans mon énoncé ils l'ont dit comme ça) et avec un niveau minimum d'imbrication

0
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 9
Modifié le 2 oct. 2022 à 15:27

Tout est dans mon propos alors.
Fais en sorte de respecter la règle du nombre de parenthèses :
il t'en faut au moins plus d'ouvrantes que de fermantes à n'importe quel temps du parcours de ta chaîne de caractères de référence.
Si à un moment la règle n'est plus respectée : tu dois insérer une parenthèse ouvrante à l'endroit où tu viens de trouver une erreur, et décaler le reste de la chaîne de caractères d'un cran histoire de ne rien effacer. De cette façon tu complètes ton texte. Ou bien tu supprimes l'erreur en question (dépiler() ??) et tu décales ta chaîne de caractères pour meubler ce trou.
Soit ton tableau initial est suffisamment grand pour supporter ce genre de manipulations, soit tu as recours à l'allocation dynamique pour adapter la taille de ton tableau à l'ajout d'un caractère.

Lorsque tu atteins la fin de ta chaîne de caractères ('\0'), si le compte des parenthèses n'est pas bon (asymétrie), de nouveau tu ajoutes autant de parenthèses fermantes que nécessaire, et tu agrandis ton tableau (comme tu as appliqué la règle des parenthèses ouvrantes en amont, ce sera forcément un défaut de parenthèses fermantes).

Sinon tu ne touches à rien.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:02

Mais ce que vous m'expliquez, c'est quand la chaîne générée est mal formée (pas le bon nombre de parenthèses ouvrantes / fermantes). En vrai de vrai, ça correspond à mon deuxième exercice mais pas le premier. Il faut que ma fonction génère un texte bien formé, c'est-à-dire avec le bon nombre d'ouvrantes et fermantes.

0
arscy Messages postés 173 Date d'inscription dimanche 26 janvier 2014 Statut Membre Dernière intervention 5 octobre 2023 9
Modifié le 2 oct. 2022 à 16:49

Il s'agit strictement du même principe.
Rien de t'empêche de contrôler ta chaîne lorsque tu la conçois, donc en temps réel.

Mais c'est bien à ce souci qu'on a tous fait allusion concernant ton premier post : formuler ta question.
J'ai l'impression que ton problème c'est que tu te demandes comment générer une chaîne de caractères aléatoires.
Le plus propre serait de passer par les codes ASCII.

https://commons.wikimedia.org/wiki/File:ASCII-Table-wide.svg


Sinon ce serait de passer par un tableau de référence dans lequel tu stockes tous les caractères que tu autorises pour confectionner ta chaîne.

Ne pas oublier de clôturer ta chaîne avec le marqueur de fin de chaîne '\0'.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:04

oui pour le truc du tableau c'est ça que j'ai essayé de faire dans mon code 

char chaine[26] = "abcdefghijklmnopqrstuvwxyz";
c = chaine[rand()%26];

Bref,  mon soucis c'est surtout comment générer ce texte avec le bon nombre de parenthèses ouvrantes et fermantes en utilisant une pile, c'est-à-dire en utilisant l'algorithme que j'ai donné dans mon post du début.

Le faire sans l'algorithme est plus facile mais utiliser la pile non.

Et moi-même je ne comprends pas trop ce que fait l'algorithme ,j'ai juste essayé de la traduire en C.

0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
2 oct. 2022 à 18:53

Quoi qu'il en soit, ton énoncé n'est pas cohérent.

Par exemple

      { c est un caractère peu importe}
	  c = caractère qui n'a pas de parenthése
      afficher c //ça veut dire qu'on n'ajoute pas c à la pile et donc la pile ne peut contenir que des parenthèses

Peux-tu vérifier, que tu l'as correctement retranscrit, mot pou moi et si

  • oui le confirmer
  • non, le recopier exactement

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:06

ok

L'énoncé complet:

L'algorithme suivant (voir algorithme de mon message #1) permet de générer une chaîne bien équilibré. On utilise la pile pour sauvegarder l'état courant du parenthésage. 

Cet algorithme n'est pas déterministe : il y a 2 options à faire à chaque pas de l'itération :

  • affiche-t-on encore des caractères ou bien s'arrête-t-on ?
  • si on continue, quel type de caractère affiche-t-on ?

La manière de faire ces choix n'est ici pas indiquée. On peut pour cela utiliser un générateur aléatoire (tout en s'assurant que la chaîne générée est bien parenthésée).

  1. Préciser les choix effectués dans l'algorithme ci-dessus afin de générer une chaîne aléatoire bien parenthésée d'une longueur minimum donnée.
  2. Préciser les choix effectués dans l'algorithme ci-dessus afin de générer une chaîne aléatoire bien parenthésée d'un niveau minimum d'imbrication donné
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
Modifié le 4 oct. 2022 à 15:58

Bien, mais l'algorithme que tu donnes ne correspond pas à ça, voir mon  "par exemple" du message 17.

Donc peux-tu vérifier que tu as correctement retranscrit l'algorithme mot pour mot ?


0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 15:58

L'algorithme sans modification de ma part :

p = PileVide()

   tant que non EstVide(p) ou il reste des caractères à imprimer
      choisir parmi :
      { c est une parenthèse ouvrante }
	  c = parenthèse ouvrante
	  Empiler(p , c)
      { c est une parenthèse fermante }
	  si non EstVide(p) alors
	     c = parenthèse fermante correspondant à Sommet(p)
             Dépiler(p)
      { c est un caractère quelconque }
	  c = caractère non parenthèse
      Afficher c
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
2 oct. 2022 à 20:15

OK, donc on peut conclure que

  1. Il n'est jamais question de crochet ou d'accolade (comme tu l'as codé plus haut) dans l'algo, ni dans l'énoncé, donc pour l'instant, on oublie ces caractères.
  2. Les caractères "quelconques" ne sont jamais empilés, juste affichés.
  3. Il n'est pas écrit que les parenthèses sont affichées dans l'algo, pourtant selon l'énoncé elles le doivent.

Tes premières étapes sont donc d'écrire les fonctions

  • PileVide()
  • EstVde()
  • Empiler()
  • Depiler()

Qui correspondent à l'énoncé, à l'algo et aux conclusions ci-dessus.


0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:07

J'ai fait:

#define TAILLE_MAX 10000

typedef struct {
  int n;
  char tab[TAILLE_MAX];
} PileCaractere;

int est_vide(PileCaractere *p) { 
  return (p->n == 0); 
}

PileCaractere PileVide(PileCaractere *p) { 
  p->n = 0;
  return *p;
}

void empiler(PileCaractere *p, char x) {
  p->tab[p->n] = x;
  p->n = p->n + 1;
}

char depiler(PileCaractere *p) {
  p->n = p->n - 1;
  return p->tab[p->n];
}
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 3 oct. 2022 à 00:45

Bon, donc, il est clair que p n'est pas un booléen et si l'algo ne correspond pas aux indications textuelles, c'est que les indications donnent simplement d'autres indications additionnelles à prendre en compte.

Aussi, l'exercice est à faire avec une pile, donc, il doit le faire avec une pile et pas un compteur.

Comme le remarque Whismeril, note que, dans l'énoncé textuel que tu nous donnes en plus de l'algo, on ne parle que de parenthèses. Pour moi les parenthèses c'est ( ou ) et c'est tout. Pas [ ], ni { } ou autres. Si tu dois traiter ces types de caractères en plus, cela se complique un peu.

La pile sert juste à empiler les parenthèses ouvrantes. Lorsqu'une parenthèse fermante doit être écrite, la parenthèse ouvrante au sommet doit être retirée. Lorsqu'on a une pile vide, c'est qu'on a traité toutes les parenthèses. C'est, en gros, la seule chose que dit la partie des indications sous forme d'algo (incomplet à dessein).

À mon sens, vu la tête des deux premières lignes de l'algorithme, il ne peut marcher que si le texte commence par une parenthèse (comme une ligne d'instructions en langage Lisp et ses dérivés) :

 p = PileVide()

   tant que non Vide(p) 

Donc, entre les deux lignes ci-dessus, il faudrait mettre sur la pile une parenthèse ouvrante, pour que l'algo exécute la boucle tant que (et afficher cette parenthèse ouvrante histoire de voir où on en est), et probablement indiquer que ce choix de conception a été fait.

Si on fait différemment, et que la ligne peut commencer par autre chose, il faudra insérer plus de code entre ces deux lignes de l'algo pour y mettre une boucle tant que l'on n'a pas inséré au moins une parenthèse ouvrante (et sans doutes cette boucle ne pourra générer que un caractère quelconque ou une parenthèse ouvrante, et pas terminer, sinon on aura une ligne sans parenthèses... et ce n'est pas le but de l'exercice a priori).

Tout cela ce sont des choix de conception.

Ensuite, les indications textuelles de l'énoncé sont importantes pour comprendre quels types de stratégie mettre en oeuvre, pour insérer dans le fonctionnement de l'algo les éléments nécessaires à la construction de la chaîne :

Cet algorithme n'est pas déterministe : il y a 2 options à faire à chaque pas de l'itération :

    affiche-t-on encore des caractères ou bien s'arrête-t-on ?
    si on continue, quel type de caractère affiche-t-on ?

La manière de faire ces choix n'est ici pas indiquée. On peut pour cela utiliser un générateur aléatoire (tout en s'assurant que la chaîne générée est bien parenthésée).

Une fois que l'on a commencé avec une parenthèse ouvrante et qu'on entre dans la boucle de l'algorithme, on peut donc utiliser des tirages aléatoires avec rand() pour décider :

  • si on affiche encore des caractères ou si on s'arrête (un tirage retournant 0 ou 1 qui s"évaluent à faux et vrai respectivement en C)
  • si on s'arrête, cela signifie qu'on doit fermer immédiatement toutes les parenthèses jusqu'à ce que la pile soit vide et c'est tout
  • si on continue, on peut continuer avec 3 types de caractères comme l'a identifié 
    Theo_0055 (un autre tirage retournant 0, 1, ou 2 peut être fait), et un enum tel que l'a proposé Theo_0055 convient parfaitement, car l'enum est un type entier qui par défaut commencera à 0 et le résultat du tirage pourra être traité avec un switch / case utilisant les membres de l'énumération pour avoir un code plus parlant

Theo_0055, est-ce plus clair ?

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:12

Ok faisons avec juste les parenthèse, et après, si je comprends avec un type, peut-être je pourrais le faire les autres.

Moi aussi cette ligne m'a perturbé un peu car si je suis sensé rentrer dans ma boucle, ma pile n'est pas sensé être vide. Or la fonction d'avant crée une pile vide. Vous avez raison, la solution est d'empiler d'abord une parenthèse ouvrante pour éviter que la pile soit vide dés le départ.

Donc, entre les deux lignes ci-dessus, il faudrait mettre sur la pile une parenthèse ouvrante, pour que l'algorithme entre dans la boucle while (et afficher cette parenthèse ouvrante histoire de voir où on en est), et probablement indiquer que ce choix de conception a été fait.

Par exemple dans la boucle while

int random = rand() % (1 - 0 + 1) = rand() % 0

Est-ce que mettre ça est correct ? Je veux que rand tire un nombre entre 0 et 1

  • Si c'est 0 qu'il retourne alors on s'arrête.
    • Si on s'arrête alors on affiche des parenthèses fermantes jusqu'à ce que le nombre de parenthèses fermantes soit égal au nombre de parenthèses ouvrantes
  • Sinon on continue

Oui pour la suite c'est plus clair. Je veux utiliser correctement mon enum. Mais j'ai remarqué que si je fais :

switch(caractere)

caractere a pour type mon enum, ça ne marche pas. Pourtant ça devrait.

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 3 oct. 2022 à 10:49

int random=rand()%(1-0+1)=rand()%0

esceque mettre ça c'est bon ?je veux que rand tire un nombre entre 0 et 1

Ta double affectation est erronée (tu ne peux pas diviser par 0) et inutile car seule la première l'est. Pour tirer soit 0 (faux), soit 1 (vrai), simplifie (1 - 0 + 1), et tu peux juste faire.

int arreter = rand() % 2;

C'est quand même plus clair :-)

Ensuite, tu as un nom parlant de variable pour faire :

if (arreter) {
        /* faire ce qu'il faut */
}

Pour ton type enum, comme pour les types struct, on peut compliquer la déclaration en ajoutant à la déclaration du type un typedef qui définit un alias sur le type. Du coup les débutants mélangent pas mal de choses sur des notions nouvelles.

Je propose de ne pas utiliser de typedef, pour bien comprendre ce que tu fais.

enum type_de_caractere { OUVRANTE, FERMANTE, QUELCONQUE };

Ceci crée un type énuméré qui s'appelle "enum type_de_caractere", où :

  • "type_de_caractere" est l'étiquette de l'enum,
  • et où OUVRANTE, FERMANTE et QUELCONQUE sont les membres du type (par convention, en C, les membres d'un enum étant des constantes définies à la compilation, on les écrit en CAPITALES)

C'est un type entier numéroté à partir de 0, sauf indication contraire, donc équivalent à 0, 1, 2.

On déclare une variable utilisant ce type, comme toute variable en C, en indiquant le nom du type (ici "enum type_de_caractere" est le nom du type) et le nom de la variable. Comme on peut ranger dedans des entiers de 0 à 2, on peut écrire :

enum type_de_caractere suivant = rand() % 3;

la variable "suivant" comporte désormais un entier de 0 à 2, et ensuite on peut construire le switch / case pour faire ce qu'il y a à faire en fonction de la valeur :

switch (suivant) {
case OUVRANTE:
        /* empiler une parenthèse et
         * l'afficher */
break;
case FERMANTE:
        /* dépiler une parenthèse et
         * l'afficher */
break;
case QUELCONQUE:
        /* tirer un caractère autre
         * qu'une parenthèse et l'afficher */
break;
}
0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:16

Je viens de comprendre pourquoi ça ne marchait pas. C'est parce que mon enum caractere (que j'ai renommé caractere) je l'ai écrit directement dans mon switch sans le déclarer.

J'au aussi testé: 

caractere c; 
switch(c) {
  ...
}

Ceci ne marchait pas non plus, car c ne contenait rien du tout.

Ok j'ai saisi

  • Pour le case Ouvrante:
empiler(&p, '(');
afficher_pile(&p);
  • Pour le case Fermante :
depiler(&p, '(');
afficher_pile(&p);
  • Pour le case Quelconque : Est ce que ma manière de procéder pour tirer un caractère est bonne ?
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 3 oct. 2022 à 12:48

Je ne suis pas sûr que tu doives afficher la pile. En revanche, tu peux afficher les caractères au fur et à mesure qu'ils sont générés, qu'il s'agisse de parenthèses ou pas. Après tout c'est bien cela que tu dois afficher : une ligne de trucs bien "parenthésée".

La manière dont tu générais des caractères aléatoires autres que des parenthèses me semble OK :-)

(ligne 47 de ton code https://forums.commentcamarche.net/forum/affich-37698018-generer-une-chaine-correctement-parenthesee#8)

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083 > [Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024
Modifié le 3 oct. 2022 à 12:51

Note que tu peux faire des tests unitaires avec rand(), en utilisant toujours la même graine d'initialisation passée à srand(), tu auras alors toujours la même suite de tirages réalisée par le générateur de nombres pseudo-aléatoire et un comportement prévisible de ton code pour les besoins de tes tests généré par le code de ton compilateur. Ou tu peux écrire une fonction rand() à toi qui génère les suites de tirages correspondant aux cas que tu veux tester (c'est mieux, mais c'est un peu plus de travail).

Pour le code en production, tu devras initialiser le le générateur de nombres pseudo-aléatoire avec srand() en début de programme en lui passant un nombre différent à chaque lancement du programme (une fois au début du programme et pas dans la boucle). Classiquement, on lui passe time(NULL) comme tu dois le savoir. C'est l’utilisation classique de rand().

https://stackoverflow.com/questions/16569239/how-to-use-function-srand-with-time-h/16569330#16569330

https://cplusplus.com/reference/cstdlib/srand/

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1 > [Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024
3 oct. 2022 à 13:22

Oui merci srand(time(NULL)) permet d’éviter d’avoir la même suite de nombre tirés aléatoirement

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 12:42

Ah oui c’est plus simple de faire printf(‘’ %c’’,c),c pour le caractère en question 

maintenant j’ai compris ce qu’il fallait faire,merci

Maintenant je veux gérer le cas des crochets et accolades ,esceque ce que j’avais fait au début c’est à dire une fonction qui génère une Ouvrante selon le fait que je tire au hasard un 0,1 ,ou autre chose est bon

Si c’est 1 on génère une parenthèse,si c’est 1 un crochet sinon une accolade

Cette méthode choisi est elle pertinente?

par exemple je tire 

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 3 oct. 2022 à 13:09

Il manque des mots ou des phrases à ton message de 12:42, je pense. Du coup, je ne suis pas sûr de saisir ce que tu veux dire.

Pour gérer les crochets et accolades en plus des parenthèses, il y a une petite complication à gérer :

  • bien sûr tu dois décider du caractère ouvrant que tu génères (tu as désormais 3 possibilités) - pour cela tu peux faire un tirage aléatoire additionnel
  • ensuite, tu ne peux fermer une parenthèse, un crochet ou une accolade avec un caractère "fermant", que si le dernier caractère "ouvrant" empilé est bien un caractère "ouvrant" correspondant. Une façon simple de faire est de tester ce qui est au sommet de la pile, pour que le bon caractère "fermant" soit ajouté, avant de dépiler le caractère "ouvrant" concerné.
0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
Modifié le 4 oct. 2022 à 16:24

Je vois : je peux pas fermer avec n'importe lequel. Il faut vérifier ce qu'il y a au sommet de la pile.

Si par exemple, j'ai une accolade ouvrante au niveau du sommet, lorsque je la dépile; il faut que j'affiche une accolade fermante pour la fermer.

Je ne peux pas par exemple générer un caractère fermant au hasard car si c'est une parenthèse fermante, l'accolade ouvrante ne sera pas fermée

Est-ce que c'est cela que vous vouliez dire ?

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 3 oct. 2022 à 18:29

Oui c'est exactement cela.

Tu peux ouvrir avec n'importe quel caractère "ouvrant", mais lorsque tu dois fermer, tu ne peux fermer qu'avec le caractère "fermant" au sommet de la pile.

0
Theo_0055 Messages postés 275 Date d'inscription mardi 21 juillet 2020 Statut Membre Dernière intervention 19 janvier 2023 1
3 oct. 2022 à 18:31

Ok je vais essayer de faire le code et je reviendrais ici le mettre

0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 931
4 oct. 2022 à 07:40

Bonjour

une option peut être quand tu affiches ( tu empiles ), quand tu affiches { tu empiles } et donc au moment de dépiler, tu as directement la bonne fermeture.


0