logo

2 petits exercices casse-tete

C'est ici que vous posterez vos questions sur la programmation en C ou en C++

2 petits exercices casse-tete

Messagede doudou12 » 18 Sep 2008, 15:41

Bonjour,

j'ai 2 petits exercices qui me cassent vraiment la tete je n'arrive meme pas a débuter.
je me suis pourtant bien exercé avec ce site. a croicre que le cpp est magique :D

les voila. si vous voulez bien m'aider.

1. Écrire un programme qui convertit un nombre romain dans sa représentation
arabe décimale. Utiliser l’algorithme :
Lire le nombre de gauche à droite. Si un chiffre est plus grand ou égal à son successeur, on
l’ajoute à la somme. Dans le cas contraire on le soustrait. Les chiffres possibles sont : I (1), V
(5), X (10), L (50), C(100), D (500), M (1000). Exemple :
MCMXCXVI = 1 000 + (1 000 - 100) + (100 - 10) + 5 + 1 = 1996


2. Écrire un programme qui « fait la monnaie » : l’usager inscrit un montant en
dollars et le programme lui propose la combinaison minimale de billets de 100,
50, 20, 10 et 5$ ainsi que des pièces de 2$ et 1$ qui a la même valeur. Par
exemple, si l’usager inscrit 533$, le programme lui dit qu’il peut réunir ce montant
avec 5 billets de 100$, 1 billet de 20$, 1 billet de 10$, 1 pièce de 2$ et 1 pièce de
1$ (le programme aurait pu préciser 0 billet de 50$ et 0 billet de 5$, mais cela
importe peu). Vous ne pouvez pas utiliser de structure de décision ni de
structure de répétition pour cet exercice.

Merci :P
doudou12
 
Messages: 5
Inscription: 18 Sep 2008, 15:37

Re: 2 petits exercices casse-tete

Messagede Tibo » 18 Sep 2008, 20:30

Salut, le but de ce forum n'est pas de donner des solutions toutes faite, mais de guider vers la solution ;)

Bon alors pour le premier programme, le plus dur, c'est de comprendre la logique de l'algorithme... J'imagine que tu connais les tableaux en C++ (mais si tu utilises les string, c'est pareil !). On va supposer que tu a donc un tableau de lettre qui correspond au nombre en chiffre romain :
Code: Tout sélectionner
char nbRomain[10];

Là on suppose qu'on a un nombre romain de 10 caractère au max... Si tu connais les string, tu peux marquer :
Code: Tout sélectionner
string nbRomain;


Maintenant, ce qu'il faut c'est parcourir ce tableau pour décoder les caractères un par un. Donc il te faut une boucle qui parcours ce tableau :
Code: Tout sélectionner
for(int i=0;i<nbRomain.lenght();i++)


Et pour chaque caractère (donc à l'intérieur de la boucle), il faut que tu testes :
si c'est un 'I', tu ajoutes 1 au résultat :
Code: Tout sélectionner
result=result+1;

si c'est un 'V', tu ajoutes 5 au résultat :
Code: Tout sélectionner
result=result+5;

si c'est un 'X', tu ajoutes 10 au résultat...

Mais (il y a toujours un mais), il faut aussi que tu testes si la valeur du caractère suivant est plus grand, car dans ce cas, il ne faut pas ajouter mais soustraire !
Je te laisse proposer ta version de l'algo final, et je te le corrigerais si besoin...

Pour l'exo 2, tu vas avoir besoin de l'opérateur modulo...
Par exemple, si tu veux savoir combien de billets de 100 il faut donner, il faut diviser le montant par 100 (C++ fait la division entière par défaut, donc si le montant est 120, le résultat de 120/100 sera 1 ; et c'est bien le nombre de billet de 100 qu'il faut donner ;-))
Ensuite, pour savoir ce qu'il reste à payer si on donne les billets de 100, il faut utiliser l'opérateur modulo (cherche sur internet pour comprendre bien ce que c'est) en écrivant :
Code: Tout sélectionner
reste=montant%100

Ainsi dans reste, il y aura 20.

En faisant 20/50, on obtient 0 (donc 0 billets de 50) puis il faut refaire
Code: Tout sélectionner
reste=montant%50

Dans reste, il y a toujours 20... Puis 20/20 donne 1 donc il faut donner 1 billet de 20...

Poste ta solution (ou pose d'autre question :mrgreen: )
Tibo
Administrateur du site
 
Messages: 147
Inscription: 26 Mar 2008, 13:58

Re: 2 petits exercices casse-tete

Messagede doudou12 » 20 Sep 2008, 09:54

Bonjour et excusez moi pour cette réponse assez tardive.

voici mon premier programme, en compilant j,ai eu quelques erreurs mais je n'arrive pas
à trouver le pourquoi:

Code: Tout sélectionner
               /* PARTIE INCLUSION DE FICHIERS */

#include <iostream>            //   Pour l'utilisation de cin et cout
#include <string>            // Pour l'utilisation de chaînes de caractères
using namespace std;
void main(void)               //   Fonction pincipale, début du programme


{               /* PARTIE DÉCLARATION */
int I=1, V=5, X=10, L=50, C=100, M=1000;
string R
char Charlu1, Charlu2;

   cout << "Entrez un chiffre romain: ";
    cin.getline('R');
   if (Carlu1>=Carlu2) Carlu2=Carlu1 + Carlu2;
   else Carlu2= Carlu1 - Carlu2
      somme=R

      cout << " la representation arabe est: " << somme;



et pour le 2e, a l'exécution ca marche mais j'ai une fenetre d'erreur lors de l'exécution

Code: Tout sélectionner
/* PARTIE INCLUSION DE FICHIERS */

#include <iostream>            //   Pour l'utilisation de cin et cout
using namespace std;
void main(void)               //   Fonction pincipale, début du programme

               /* PARTIE DÉCLARATION */

{
   int C, Ci, V, D, Cq;
   int montant;

   cout << "Entres un momntant";
      cin >> montant;
   C= montant/100;
      cout << " il y'a: " << C << "billets de cent";
      Ci=montant%100;
      montant = Ci/50;
      cout << " il y'a: " << V << "billets de cinquante";
      V = montant%50;
      montant = V/20;
      cout << " il y'a: " << D << "billets de vingt";
      D = montant%20;
      montant = D/10;
      cout << " il y'a: " << Cq << "billets de dix";
      Cq = montant%10;
      montant = Cq/5;
      cout << " il y'a: " << Cq << "billets de conq";
}


Merci encore pour votre aide :)
doudou12
 
Messages: 5
Inscription: 18 Sep 2008, 15:37

Re: 2 petits exercices casse-tete

Messagede Tibo » 20 Sep 2008, 14:18

Salut,
en effet, il y a quelques erreurs...
Les premières sont simples à corriger, c'est des oublis ! Par exemple, il y a des lignes où il manque des ;... Ensuite, pour le cin.getLine('R'), ça ne peut pas marcher car la fonction getLine attends une variable entre les parenthèses, et toi, tu lui donne le caractère R !En fait, il ne faut pas mettre R entre guillemets mais le laisser tous seul pour que l'ordi sache que c'est une variable (et non la simple lettre R) : donc il faut mettre :
Code: Tout sélectionner
cin.getLine(R)

Ensuite, il faut bien respecter les noms des variables : un coup tu les appelles Charlu1, puis Carlu1... Met les mêmes nom partout ;)

Enfin, et là c'est un problème un peu plus complexe, c'est que la logique du programme n'est pas bonne...
Le début est bon : tu demande à l'utilisateur de saisir un nombre en lettre, et tu mets la ligne que l'utilisateur a saisi dans la variable R (a ce propos, tu devrais donner des nom pour les variables un peu plus compréhensible, genre nombreRomain...)
C'est après que ça se gate... En effet, une fois que tu as le nombre de l'utilisateur enregistré, il faut que tu l'analyses lettre par lettre (grâce aux deux variables que tu as faite : Charlu1 et Charlu2...). Pour ça, il te faut une boucle (le mieux, c'est d'utiliser une boucle for...) :
Code: Tout sélectionner
for(int i=0;i<R.length();i++){
Charlu1=R[i];
Charlu2=R[i+1];

Maintenant, dans Charlu1 on a la lettre en ième position et dans Charlu2 on a la lettre suivante.Donc la condition du if que tu avais faite est bonne, mais les conditions ne sont pas bonnes...
Que penses-tu de celle là :
Code: Tout sélectionner
      if (Carlu1>=Carlu2) {
         switch (Carlu1){
         case 'I':somme=somme+1;
            break;
         case 'V':somme=somme+5;
            break;
         case 'X':somme=somme+10;
            break;
         case 'L':somme=somme+50;
            break;
         case 'C':somme=somme+100;
            break;
         case 'M':somme=somme+1000;
            break;
         }
      }else{
         switch (Carlu1){
         case 'I':somme=somme-1;
            break;
         case 'V':somme=somme-5;
            break;
         case 'X':somme=somme-10;
            break;
         case 'L':somme=somme-50;
            break;
         case 'C':somme=somme-100;
            break;
         case 'M':somme=somme-1000;
            break;
         }
      }

Pour finir, il faut que tu déclares la variable somme au début du programme car on en a besoin (au passage, tu peux supprimer les variables I,V,X ... car on les utilises pas ;) )

Essaye de remettre tout ça dans l'ordre, et si t'y arrive vraiment pas, je peux te poster le programme...

Pour l'exo 2, t'es presque à la solution !!!
Quand tu écris cette ligne :
Code: Tout sélectionner
   cout << " il y'a: " << V << "billets de cinquante";

Poses toi la question suivante : quelle valeur contient cette variable ?
Tu te rendra compte alors de ton erreur (très facile, cherche pas trop compliqué!!!)
Et du coup, ton programme marchera !

Bon courage, et surtout ne perd pas espoir, au début, la logique parait incompréhensible, et petit à petit, ça te paraitra simple !
Tibo
Administrateur du site
 
Messages: 147
Inscription: 26 Mar 2008, 13:58

Re: 2 petits exercices casse-tete

Messagede doudou12 » 21 Sep 2008, 07:42

Bonjour Tibo :D ,

voila pour le premier je pense que tout est correcte, dans la démarche, la logique et le contenu.

voici le code tout mis en ordre.

Code: Tout sélectionner
   /* PARTIE INCLUSION DE FICHIERS */

#include <iostream>            //   Pour l'utilisation de cin et cout
#include <string>            // Pour l'utilisation de chaînes de caractères
using namespace std;
void main(void)               //   Fonction pincipale, début du programme


{               /* PARTIE DÉCLARATION */
int somme, i;
string nombreromain;
int Charlu1, Charlu2;

   cout << "Entrez un chiffre romain: ";
    cin.getline(nombreromain);
   for(int i=0;i<nombreromain.length();i++)
   {
      Charlu1=nombreromain[i];
      Charlu2=nombreromain[i+1];

     if (Charlu1>=Charlu2)
     {
       switch (Charlu1)
       {
         case 'I':somme=somme+1;
            break;
         case 'V':somme=somme+5;
            break;
         case 'X':somme=somme+10;
            break;
         case 'L':somme=somme+50;
            break;
         case 'C':somme=somme+100;
            break;
         case 'M':somme=somme+1000;
            break;
         }
      }
     else
     {
        switch (Charlu1)
       {
         case 'I':somme=somme-1;
            break;
         case 'V':somme=somme-5;
            break;
         case 'X':somme=somme-10;
            break;
         case 'L':somme=somme-50;
            break;
         case 'C':somme=somme-100;
            break;
         case 'M':somme=somme-1000;
            break;
         }
      }
   }

      cout << " la representation arabe est: " << somme;
}


A l'exécution, j'obtiens juste une seule erreur:
1>c:\users\documents\visual studio 2008\projects\mesdebuts\exercice5\exo5.cpp(26) : warning C4018: '<' : incompatibilité signed/unsigned

je pense que c'est dû a l'utilisation du for, j'ai essayé de remplacer par un while rien de changé. :cry:

******************************************************************

pour le 2e,
Poses toi la question suivante : quelle valeur contient cette variable ?


elle contient la valeur précédente ou plutot le résultat du modulo. d'apres l'exercice je pense que c'est cette valeur que je dois utilisé parceque je ne pense pas qu'il y ai une autre alternative; sinon comment puis je faire comprendre au programme qu'il doit tout le temps utiliser la meme valeur ?

Un très très grand merci encore je comprends bien mieux avec vous bizarrement qu'en classe :) .
doudou12
 
Messages: 5
Inscription: 18 Sep 2008, 15:37

Re: 2 petits exercices casse-tete

Messagede Tibo » 21 Sep 2008, 12:32

Salut !
Pour le premier exo, j'ai pas testé ta solution, mais ça m'a l'air bien :) . Pour l'erreur, pas de problème, c'est juste un warning ("attention") qui te dit que tu compares un nombre non signé avec un nombre signé (rappel : non signé veut dire que c'est un nombre uniquement positif !). En effet, la fonction nombreromain.length() renvoi un nombre non signé (toujours positif) et i est un int normal (donc avec un signe...)
Pour enlever ce warning, tu peux rajouter unsigned devant la déclaration de i :
Code: Tout sélectionner
for(unsigned int i;i<nombreromain.length();i++)


Pour l'exo 2, tu n'as pas bien regardé ce que tu avais marqué... Fait attention, c'est une erreur fréquente qu'il faut absolument perdre !
Le C++, c'est comme un texte : tu lit la première ligne, puis la deuxième et ainsi de suite... Donc quand tu écris :
Code: Tout sélectionner
cout << "Entres un momntant";
      cin >> montant;
   C= montant/100;
      cout << " il y'a: " << C << "billets de cent";
      Ci=montant%100;
      montant = Ci/50;
      cout << " il y'a: " << V << "billets de cinquante";

moi, je lis :
1ère ligne : tu affiche un message à l'écran (avec une belle faute ;) )
2ème ligne : tu mets la valeur de l'utilisateur dans la variable montant (par exemple 351)
3ème ligne : tu mets dans la variable C le résultat de la division de la valeur qu'il y a dans la variable montant par 100 (donc 3)
4ème ligne : tu affiche le contenu de la variable C (donc 3)
5ème ligne : tu mets dans la variable Ci le résultat du modulo 100 de la valeur qu'il y a dans la variable montant (donc 51)
6ème ligne : tu mets la valeur de Ci/50 dans la variable montant (donc 1)
7ème ligne : tu affiches le contenu de la variable V... Mais tu n'a rien mis dans la variable V!

Donc l'erreur est ici... Que dois tu afficher en réalité ?

Poste donc la réponse, je penses que maintenant tu n'auras plus de problème pour corriger toutes les autres erreurs (qui sont sur le même style de problème).
Tibo
Administrateur du site
 
Messages: 147
Inscription: 26 Mar 2008, 13:58

Re: 2 petits exercices casse-tete

Messagede doudou12 » 22 Sep 2008, 00:23

J'ai pu changer l'avertissement en changeant l'ecriture du get line, j'ai mis
ca: au lieu de ca:
mais dans la console, il semblerai qu'on ait oublié d'initialiser la variable somme:

ex du print screen: http://images4.hiboox.com/images/3908/8 ... 8d5110.jpg

j'ai donc délibérément donné comme valeur zéro. c'est la valeur de départ il me semble.
si je prends l'exemple de l'exercice: MCMXCXVI = 1996
mais lorsque je l'exécute dans mon programme, j'obtiens - 174 comme valeur.

*************************************************
7ème ligne : tu affiches le contenu de la variable V... Mais tu n'a rien mis dans la variable V!
c'ets vrai j'ai fais une inversion :oops: :oops: :oops: :oops:

oops. merci pour tout.
doudou12
 
Messages: 5
Inscription: 18 Sep 2008, 15:37

Re: 2 petits exercices casse-tete

Messagede Tibo » 22 Sep 2008, 09:50

Salut,
On y est presque ;)
Pour le premier prog, fait attention à retrer le nombre avec des majuscules, car on compare le nombre avec des lettres majuscules.
Pour que ça marche même avec des minuscules, il faut modifier le switch...case comme ça :
Code: Tout sélectionner
if (Carlu1>=Carlu2) {
         switch (Carlu1){
         case 'i':
         case 'I':somme=somme+1;
            break;
         case 'v':
         case 'V':somme=somme+5;
            break;
         case 'x':
         case 'X':somme=somme+10;
            break;
         case 'l':
         case 'L':somme=somme+50;
            break;
         case 'c':
         case 'C':somme=somme+100;
            break;
         case 'm':
         case 'M':somme=somme+1000;
            break;
         }
...


En esperant que maintenant, ça marche !

Bon courage pour la suite !
Tibo
Administrateur du site
 
Messages: 147
Inscription: 26 Mar 2008, 13:58

Re: 2 petits exercices casse-tete

Messagede doudou12 » 22 Sep 2008, 11:18

Ca marche quand je mets un chiffre romain plus petit que son successeur.
ex: xm ; mais quand je mets mx, la réponse est négative.
peut etre qu'il serait judicieux de refaire un autre if la reponse est négative, prendre la valeur absolue.

merci beaucoup
doudou12
 
Messages: 5
Inscription: 18 Sep 2008, 15:37


Retourner vers Cpp

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités

cron
Hit-Parade des sites francophones