Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1274 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Besoin d'aide pour trouver mon erreur

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Besoin d'aide pour trouver mon erreur

n°2330899
grockes
Posté le 26-03-2019 à 11:31:31  profilanswer
 

Bonjour,
 
J'apprends à mon rythme à programmer en C++. Pour m'aider, je navigue entre plusieurs sites.
On me propose un exercice dont voici un résumé du sujet:
 
"Une opération de lissage d'une séquence de mesures (des nombres décimaux) consiste à remplacer chaque mesure sauf la première et la dernière, par la moyenne des deux valeurs qui l'entourent.
Par exemple, si l'on part de la séquence de mesures suivantes :
1 3 4 5
On obtient après un lissage :
1 2.5 4 5
Le premier et dernier nombre sont inchangés. Le deuxième nombre est remplacé par la moyenne du 1er et du 3e, soit (1+4)/2 = 2.5
Votre programme doit calculer le nombre minimum de lissages successifs nécessaires pour s'assurer que la valeur absolue de la différence entre deux valeurs successives de la séquence finale obtenue ne dépasse jamais une valeur donnée, diffMax."

 
Ensuite les exigences demandés sur le site pour le programme:
 
Entrée
La première ligne de l'entrée contient un entier : nbMesures.
La deuxième ligne de l'entrée contient un nombre décimal : diffMax.
Chacune des nbMesures lignes suivantes contient une mesure, sous la forme d'un nombre décimal.
 
Sortie
Vous devez afficher un entier sur la sortie : le nombre minimal de lissages nécessaire.

 
Enfin le programme que j'ai écrit:
 

Code :
  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. int main ()
  5. {
  6.    int nbMesure, nbLissage =0;
  7.    cin >> nbMesure;
  8.    double diffMax, mesure[nbMesure], difference[nbMesure -1], diffLaPlusGrande = 0;
  9.    cin >> diffMax;
  10.    for (int iMes(0); iMes < nbMesure; iMes++)
  11.       cin >> mesure[iMes];
  12.    do
  13.    {
  14.       for (int i(1); i < nbMesure - 2; i++)   //lissage
  15.       { 
  16.          mesure [i] = (mesure[i-1] + mesure[i+1])/2;
  17.          nbLissage++;
  18.       }
  19.       for (int iDiff (0); iDiff < nbMesure - 1; iDiff++) // calcul diff
  20.       {
  21.          difference [iDiff] = abs (mesure [iDiff] - mesure [iDiff+1]);
  22.          if (difference[iDiff] > diffLaPlusGrande)   // Mémorisation de la plus grande différence
  23.             diffLaPlusGrande = difference [iDiff];     
  24.       }
  25.    }
  26.    while (diffLaPlusGrande >= diffMax);
  27.    cout << nbLissage << endl;
  28. }


 
Quand je fais des tests, suivant les valeurs que je donne, soient il fonctionne, soit il est trop long.
J'ai beau me casser la tête, je ne trouve pas mon erreur...
Je ne vous demande pas de me donner une réponse ou une solution mais simplement de me dire où est mon erreur.
 
Merci d'avance.
Grockes

mood
Publicité
Posté le 26-03-2019 à 11:31:31  profilanswer
 

n°2330910
rat de com​bat
attention rongeur méchant!
Posté le 26-03-2019 à 16:06:43  profilanswer
 

Je pense que ligne 15 la condition c'est plutôt i < nbMesure - 1 non?
Sinon tu peux donner quelque valeurs à entrer dans le logiciel pour se rendre compte du problème?

n°2330911
rufo
Pas me confondre avec Lycos!
Posté le 26-03-2019 à 16:11:38  profilanswer
 

La ligne 9 me paraît un peu suspecte dans la déclaration mesure[nbMesure] et difference[nbMesure -1]
 
Faudrait pas faire un truc du genre :
int nbMesure;    
std::cin >> nbMesure;
double *mesure = new double[nbMesure];
:??:
Bon après, ça fait bien longtemps que j'ai pas refait de C++.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2330921
Farian
Posté le 27-03-2019 à 10:10:30  profilanswer
 

Bonjour !  
 
Je pense qu'il y a une erreur d'algorithme, et qu'il faudrait sauvegarder les valeurs "moyennées" dans un autre tableau. J'explique mon point de vue avec le même exemple que l'énoncé :
 
Avant : 1 3 4 5
 
on fait "mesure[1] = (mesure[0] + mesure[2])/2  
->  1 2.5 4 5
 
 On fait "mesure[2] = (mesure[1]+mesure[3])/2
-> 1 2.5 3.75 5 au lieu de 1 2.5 4 5
 
De plus, je suis tout à fait d'accord avec la remarque de rat de combat.
 
Qui plus est, il faudrait remettre à 0 la valeur "diffLaPlusGrande" à chaque étape (dans la boucle "do" ) car si, comme on l'espère, la différence est amenée à baisser (en valeur absolue) à chaque itération, on reste bloqué à la valeur obtenue lors de la première, ce qui correspond au diagnostic : Soit ça va très vite, soit c'est très long, et même plus, car on ne sort jamais.
 
Et, juste pour terminer, le tableau "difference" ne sert à rien, vu qu'on consomme tout de suite la valeur calculée, on pourrait utiliser une variable de type double pour faire le calcul intermédiaire et comparer le résultat au max de ce coup-ci.
 
 
Voilà, avec toutes ces corrections, cela devrait aller mieux :)
 
Bonne continuation !


---------------
On n'est jamais très fort pour ce calcul !
n°2330922
grockes
Posté le 27-03-2019 à 10:32:40  profilanswer
 

Merci pour vos réponses!
 
Je vais faire des essais pour remettre diffLaPlusGrande à zéro à chaque tour. Effectivement, je n'avais pas pensé qu'on veut que la valeur baisse à chaque "lissage".
 
Pour en revenir à la ligne 15, la 1ere et la dernière mesure restent constante donc ça fait bien nbMesure -2.
 
Le lissage se fait avec les anciennes valeurs et ne s'ajuste pas au fur et à mesure... leur exemple est donc juste... Mais faut que je revois ma façon de faire pour voir si je fais comme l'exemple ou comme Farian viens de l'expliquer.
 
En tout cas, encore merci j'ai des pistes d'améliorations!

n°2330932
rat de com​bat
attention rongeur méchant!
Posté le 27-03-2019 à 13:29:02  profilanswer
 

grockes a écrit :

Pour en revenir à la ligne 15, la 1ere et la dernière mesure restent constante donc ça fait bien nbMesure -2.

Tu as une comparaison stricte, du coup il faut -1 pour aller jusqu'à l'avant-dernière valeur qui se trouve en [nbMesure-1-1]. La valeur limite que tu indiques n'est jamais atteinte (comparaison stricte)!

n°2330933
gilou
Modérateur
Modzilla
Posté le 27-03-2019 à 14:24:21  profilanswer
 

J'ai pas testé (je suis au taff) mais a vue de nez, je tenterais un truc de ce genre :  

Code :
  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. int main ()
  5. {
  6.   int nbMesure;
  7.   cin >> nbMesure;
  8.  
  9.   double diffMax;
  10.   cin >> diffMax;
  11.  
  12.   double mesure[nbMesure];
  13.   for (int i = 0; i < nbMesure; ++i) {
  14.       cin >> mesure[i];
  15.   }
  16.  
  17.   int diffPlusGrande, nbLissage = 0;
  18.  
  19.   do {
  20.     for (int i = 1; i < nbMesure-1; ++i) {
  21.       mesure [i] = (mesure[i-1] + mesure[i+1])/2;
  22.     }
  23.     ++nbLissage;
  24.    
  25.     diffPlusGrande = 0;
  26.     for (int i = 0; i < nbMesure-1; ++i) {
  27.       if (abs(mesure[i] - mesure [i+1]) >= diffMax) {
  28.         diffPlusGrande = 1;
  29.         break;
  30.       }
  31.     }
  32.   } while (diffPlusGrande);
  33.   cout << nbLissage << endl;
  34.   return(0);
  35. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2330941
Farian
Posté le 27-03-2019 à 16:18:11  profilanswer
 

Code élégant, Gilou !
 
Sauf que ma remarque sur l'écrasement des mesures au fur et à mesure du calcul  reste vraie et cela ne correspond pas à l'algorithme tel que décrit dans l'énoncé.
 
Bonne continuation !


---------------
On n'est jamais très fort pour ce calcul !
n°2330946
gilou
Modérateur
Modzilla
Posté le 27-03-2019 à 17:09:34  profilanswer
 

Farian a écrit :

Code élégant, Gilou !

 

Sauf que ma remarque sur l'écrasement des mesures au fur et à mesure du calcul  reste vraie et cela ne correspond pas à l'algorithme tel que décrit dans l'énoncé.

 

Bonne continuation !

Oui, tu as parfaitement raison, j'en rougis de honte :o
J'aurais pas eu l'esprit occupé à déployer un patch en prod, je m'en serais probablement rendu compte.

 

bon ben on va utiliser des temporaires alors pour stocker avant modification et réutilisation alors.

 

do {
    double temp1= mesure[0];
    for (int i = 1; i < nbMesure-1; ++i) {
      double temp2 = mesure[i];
      mesure [i] = (temp1 + mesure[i+1])/2;
      temp1 = temp2;
    }

 

Mais par contre, il y a un pb avec la fonction de lissage: en prenant un facteur 1/2, on peut boucler a l'infini sur une suite constante.
E.G. 1, 3, 4, 5, va boucler au bout de 52 itérations sur 1, 2+1/3, 3+2/3, 5. En effet (1 + 3 + 2/3)/2 = 14/6 = 2+1/3 et (2 + 1/3 + 5)/2 = 22/6 = 3 + 2/3
Si on veut éviter ce phénomène, il faut vérifier que l'on atteint pas une valeur constante. Et comme on a des floats...

 

A+,


Message édité par gilou le 27-03-2019 à 18:27:20

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2331011
grockes
Posté le 28-03-2019 à 13:31:41  profilanswer
 

Merci Gilou, je n'avais pas pensé non plus à mettre un Break!
 
Je pense que ta solution des temporaires doit être bonne, mais je vais devoir m'en passer car je ne l'ai pas encore abordé dans les cours que je suis.
Par contre, je vais voir si je trouve des infos là-dessus ça me paraît très intéressant!
 
Je ne vais pas copier ton programme (ou peut-être juste pour le tester) mais il sera source d'inspiration.
 
Et merci aussi aux autres, je n'ai pas encore eu le temps de modifier mon programme, mais j'ai déjà plusieurs pistes pour arriver à mes fins!

mood
Publicité
Posté le 28-03-2019 à 13:31:41  profilanswer
 

n°2331039
gilou
Modérateur
Modzilla
Posté le 29-03-2019 à 11:23:50  profilanswer
 

> Je pense que ta solution des temporaires doit être bonne, mais je vais devoir m'en passer car je ne l'ai pas encore abordé dans les cours que je suis.  
Mais il y a rien de spécial la : je définis deux variables ordinaires que j'utilise pour stocker temporairement des valeurs utilisées dans (et susceptibles d'être modifiées par) les calculs.
 
A+,


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

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Besoin d'aide pour trouver mon erreur

 

Sujets relatifs
Aide vba word choix dans une liste.bat erreur [ ( était inattendu. ]
[AIDE] Highcharts - graphique en fonction d'une var ID et TimeAide SDL audio
besoin d'aide Shell/bash svpImpossible de faire un slider besoin d'aide
Paralléliser les tris à l'aide de forkaide Spring boot /jquery /api
Besoin d'aide pour trouver un erreur 
Plus de sujets relatifs à : Besoin d'aide pour trouver mon erreur


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR