[C] Aide pour petit exo 2

Aide pour petit exo 2 [C] - C - Programmation

Marsh Posté le 04-06-2012 à 02:10:41    

Bonsoir,

 

En fait j'aimerais savoir, comment, dans un tableaux de booléens aléatoire en C, je pourrais faire pour additionner les suites de 1 (qui correspondent à une place de spectacle libre).

 

En fait l'exo consiste à réserver un nb de place consécutif demandé par un client, retourner la position du 1er si elles sont dispo et -1 si pas de places dispo, mais je vois pas trop comment m'y prendre, j'ai fais un code mais il lâche à partir du nombre de sièges.

 

Le salle[j] + salle[j+1] est faux vu que ça va additionner même les zéros, mais je sais pas comment faire pour additionner des éléments identiques consécutifs et renvoyer leur position, merci de l'aide

 
Code :
  1. int test_OK()
  2. {
  3.     int *salle=NULL;
  4.     int j=0;
  5.     int somme=0;
  6.     int places;
  7.     int demande;
  8.     printf("Entrez le nombre de place dans la salle:  " );
  9.     scanf("%d",&places);
  10.     salle=malloc(places * sizeof(int));
  11.     srand(time(NULL));
  12.     for(j=0;j<places;j++)
  13.     {
  14.         salle[j]=rand()%2;
  15.         printf("Place numero %d: %d\n\n",j,salle[j]);
  16.     }
  17.     printf(" Combien de sieges consecutifs voulez vous ? " );
  18.     scanf("%d",&demande);
  19.     for(j=0;j<places;j++)
  20.     {
  21.         if(salle[j] + salle[j+1]==demande)
  22.         {
  23.             printf("votre nb de places est dispo, la position du 1er est: %d", j);
  24.         }
  25.     }
  26.     return -1;
  27. }



Message édité par bakkiesboucher le 04-06-2012 à 15:08:33
Reply

Marsh Posté le 04-06-2012 à 02:10:41   

Reply

Marsh Posté le 04-06-2012 à 08:26:52    

Avant de se lancer dans le code, il faut au moins avoir un algo correct. Or ce n'est pas le cas.
Comment ferais-tu la recherche si tu la faisais "à la main" ?

Reply

Marsh Posté le 04-06-2012 à 15:11:54    

et bien je parcours le tableau jusqu'à tomber sur un 1, je récupère sa position et je regarde si les éléments position+1 sont des 1 jusqu'au nombre de sièges voulus non ?

Reply

Marsh Posté le 04-06-2012 à 15:56:56    

Et il se passe quoi quand la position est la dernière du tableau et que tu vérifies la position+1 ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 04-06-2012 à 16:38:25    

beh ça marche pas, je mets un exit() si la position=places

Reply

Marsh Posté le 04-06-2012 à 16:41:02    

bakkiesboucher a écrit :

et bien je parcours le tableau jusqu'à tomber sur un 1, je récupère sa position et je regarde si les éléments position+1 sont des 1 jusqu'au nombre de sièges voulus non ?

Ce n'est pas ce que fait ton code.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-06-2012 à 16:43:24    

bakkiesboucher a écrit :

beh ça marche pas, je mets un exit() si la position=places

au rang d'avant, j vaut places - 1, et tu regardes
salle[j] + salle[j+1] soit salle[places - 1] + salle[places - 1+1] c'est a dire salle[places - 1] + salle[places].
Et ils varient de combien à combien, les éléments de salle?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-06-2012 à 17:23:49    

Et la fuite de mémoire, tu l'as vue ou pas ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 04-06-2012 à 17:27:05    

oui, je rajouterais un free, mais c'est bon c'est résolu...

Reply

Marsh Posté le 04-06-2012 à 18:12:06    

ça donne ça, apparemment pas d'erreur :??:  
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int test_OK()
  4. {
  5.     int *salle=NULL;
  6.     int j=0,i=0;
  7.     int somme=0;
  8.     int places;
  9.     int demande;
  10.     int cpt;
  11.     int indice;
  12.     printf("Entrez le nombre de place dans la salle:  " );
  13.     scanf("%d",&places);
  14.     salle=malloc(places * sizeof(int));
  15.     srand(time(NULL));
  16.     for(j=0;j<places;j++)
  17.     {
  18.         salle[j]=rand()%2;
  19.         printf("Place numero %d: %d\n\n",j,salle[j]);
  20.     }
  21.     printf(" Combien de sieges consecutifs voulez vous ? " );
  22.     scanf("%d",&demande);
  23.     while (i < places)
  24.     {
  25.       while ((i < places) && (salle[i] != 0))
  26.       {
  27.             i++;
  28.       }
  29.            if (i < places)
  30.            {
  31.              indice = i; cpt = 0;
  32.                while ((i < places) && (salle[i] == 0))
  33.                {
  34.                   i++;
  35.                   cpt++;
  36.                }
  37.                    if (cpt >= demande)
  38.                     {
  39.                       return indice;
  40.                     }
  41.            }
  42.       i++;
  43.     }
  44. return -1;
  45. free(salle);
  46. }
  47. int main()
  48. {
  49.    test_OK();
  50. }

Reply

Marsh Posté le 04-06-2012 à 18:12:06   

Reply

Marsh Posté le 04-06-2012 à 19:37:37    

J'aurais pondu ceci, qui me semble logique:

Code :
  1. for (i = 0; i <= (places - demande); ++i) {
  2.      for (j = 0; j < demande; ++j) {
  3.          if (salle[i+j]) {
  4.              i += j;
  5.              break;
  6.          }
  7.     }
  8.     if (j == demande) {
  9.         printf("votre nb de places est dispo, la position du 1er est: %d", i);
  10.         break;
  11.     }
  12. }


On cherche au i-ème siège s'il y a demande sièges libres consécutifs (la boucle interne)
Si on trouve un siège occupé lors de la boucle interne, on positionne i dessus et on sort.  
La fin de la boucle externe avec le ++i positionne i après ce siège occupé, pour recommencer la recherche.
Sinon, on sort de la boucle interne avec j == demande, ce qu'on teste pour voir s'il faut sortir de le boucle externe.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-06-2012 à 20:46:21    

Il se passe quoi si l'utilisateur indique qu'il existe 4 294 967 297 de places dans la salle ?

 

edit: de toute façon, ça pètera quel que soit le nombre saisi...

Message cité 1 fois
Message édité par Harkonnen le 04-06-2012 à 20:48:42

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 04-06-2012 à 21:16:37    

Harkonnen a écrit :

Il se passe quoi si l'utilisateur indique qu'il existe 4 294 967 297 de places dans la salle ?

 

edit: de toute façon, ça pètera quel que soit le nombre saisi...

 

c'est bon j'ai rajouté un exit(0) si places>1000 ou <=0

 
Harkonnen a écrit :

edit: de toute façon, ça pètera quel que soit le nombre saisi

 

why ? de 1 à 999 sa marche chez moi

 

ps: Merci de ta réponse gilou

Message cité 1 fois
Message édité par bakkiesboucher le 04-06-2012 à 21:20:28
Reply

Marsh Posté le 04-06-2012 à 21:32:32    

c'est bon j'ai rajouté un exit(0) si places>1000 ou <=0

Le problème n'est pas là, renseigne-toi sur malloc.
Regarde aussi les bornes des boucles.

Reply

Marsh Posté le 04-06-2012 à 22:36:54    

bakkiesboucher a écrit :


 
c'est bon j'ai rajouté un exit(0) si places>1000 ou <=0
 


c'est dégueulasse comme solution : il se passe quoi si ton utilisateur saisit des lettres par exemple ?
1ère chose à savoir avec scanf() : TOUJOURS vérifier le nombre retourné par la fonction qui indique le nombre de formattages réussis. Si ce nombre == 0, alors le scanf a échoué et tu le signales.
2ème chose : toujours spécifier une chaine de formattage la plus proche possible de ce que tu souhaites que l'user rentre, car il ne faut JAMAIS faire confiance aux saisies de l'utilisateur (surtout avec scanf(), remplace le par fgets() chaque fois que tu peux).
Ainsi, ici, si tu veux que ton utilisateur ne saisisse qu'un nombre compris entre 1 et 999, alors une solution pourrait être :

Code :
  1. if (scanf("%3d", &places) == 0)
  2. {
  3.    printf("Saisie incorrecte.\n" );
  4.    exit(-1);
  5. }
  6.  
  7. if (places == 0)
  8. {
  9.    printf("Veuillez entrer un nombre de places différent de 0.\n" );
  10.    exit(-1);
  11. }
  12.  
  13. // suite de ton programme


mais comme je te disais, préfère l'emploi de fgets() à scanf(), beaucoup plus sécurisé.
 

bakkiesboucher a écrit :


 
why ? de 1 à 999 sa marche chez moi
 


au temps pour moi, j'ai lu de travers (même si ça serait mieux d'initialiser tes variables)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 04-06-2012 à 23:05:52    

Ok merci de l'aide Harkonnen, le fgets et les précisions sur le scanf, on ne nous les a pas enseignés à la fac.

Reply

Marsh Posté le 04-06-2012 à 23:38:04    

Et puis surtout,  

Citation :

salle=malloc(places * sizeof(int));


Vérifier que le malloc n'a pas échoué et que salle n'est pas NULL.
Bon, c'est sur que de nos jours, ça doit pas être courant, vu la taille des mémoires, mais autant prendre les bonnes habitudes.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-06-2012 à 00:06:03    

Perso l'algo je l'aurais fait plutôt sur un compteur de places vides consécutives, ça évite la double boucle, non ? (je pense que c'est l'algo qu'attend le prof :) )  

Code :
  1. int compteur_consecutif = 0;
  2. int position_vide = -1;
  3. for (i = 0; i < places; ++i) {
  4.     if(salle[i]){
  5.         compteur_consecutif++;
  6.         if(compteur_consecutif==demande){
  7.               position_vide = i-demande;
  8.         }
  9.     }
  10.     else{
  11.         compteur_consecutif=0
  12.     }
  13. }


 
EDIT : oouupppps j'avais pas vu le i+=j dans la boucle de gilou, mea culpa, ce n'est pas une "vraie" double boucle


Message édité par dreameddeath le 16-06-2012 à 00:15:06
Reply

Marsh Posté le 16-06-2012 à 11:15:50    

Dans mon algo, contrairement au tien, salle[i] vaut 1 si la place est occupée (ça me semblait logique) et c'est optimisé pour pas compter a partir de positions pour i dont on sait que ça va échouer, d'ou le i+=j; et l’arrêt de boucle avec i <= (places - demande).
 
Une suite logique et utile de cet algo serait de lui faire pondre la liste des place proposées possibles, et non pas seulement la première.
A+,


Message édité par gilou le 16-06-2012 à 11:20:15

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-06-2012 à 13:25:59    

pour le if(salle[i]) ==> erreur de ma part, je ne devrais pas poster à minuit...
 
Mais finalement ton j est bien l'équivalent strict de mon compteur "consécutif", sauf que je trouve qu'avec la seconde boucle imbriquée, c'est moins "visible/lisible", mais ce n'est qu'une question de point de vue.
Maintenant si la demande évolue vers de contraintes plus compliquées, la logique "look-ahead" explicite est largement plus adapté.
 
Pour faire l'équivalent de ton optim (mais je ne cherchais pas à optimiser) pour sortir quand on sait qu'il n'y a plus de possibilités, faut que je rajoute des "break"
 
Le code (car au final c'est le même algo) corrigé (je l'espère)

Code :
  1. int compteur_consecutif = 0;
  2. int position_vide = -1;
  3. for (i = 0; i < places; ++i) {
  4.     if(salle[i]==0){
  5.         compteur_consecutif++;
  6.         if(compteur_consecutif==demande){
  7.               position_vide = i-demande;
  8.               break;
  9.         }
  10.     }
  11.     else if(i>=(places-demande)){
  12.         break;
  13.     }
  14.     else{
  15.         compteur_consecutif=0
  16.     }
  17. }


 
Sinon, je suis d'accord que la suite serait plutôt autour de
- donner la liste des possibilités
- la gestion de rangs
- a chaque place correspond un prix, et proposer la liste des solutions possibles avec le prix cumulé associé.
 
A+


Message édité par dreameddeath le 16-06-2012 à 13:26:29
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed