|
|
|
|
Posté par
nuleninfo, le mardi 30 janvier 2007 à 18:31:24Comment définir les intervalles?
Disons que tu n'as pas besoin de les définir à proprement dit. Imagine que tu veuilles compter les nombres de l'intervalle ]0,2] On prend un tableau de réel comme celui de l'exemple: double tab[] = {8.3, 6.5, 7.2, 6.5, 3.4, 2.5, 3.5, 4.9, 7.3, 6.2, 1.5, 0.3, 5.8, 7.6, 3.9, 8.2 };
Puis on crée une fonction qui retourne le nombre d'élements compris dans ]0,2]: int nb_intervalle02(double *tableau, int longueur)
{
//On part de zero nombre dans cet intervalle
int nb_inter=0;
int i;
//On parcoure chaque champs
for (i=0; i< longueur; i++)
{
//Le champs examiné est t'il dans le bon interval?
if (tableau[i] >0 && tableau[i] <= 2){
//Si c'est vrai, on incrémente notre compteur de nombre dans l'interval
nb_inter++;
}
}
return nb_inter;
}
//On teste la fonction:
int main()
{
printf("%d\n", nb_intervalle02(tab, sizeof(tab)));
return 0;
}
Dans cette fonction, l'idéal est de vérifier chaque cas: le nombre est t'il dans l'interval ]0, 2] alors on incrémente le compteur approprié, sinon est t'il dans l'interval ]2 , 4] alors on incrémente un autre compteur associé à cet intervalle etc.... Ca ne résout pas tous tes problèmes mais voilà déjà quelques indications. ..et le...le...enfin, non parce c'est...ya...quand...bah tu sais là le... |
Pour le premier exo, il faut ranger dans une structure décrivant les valeurs de ton histogramme. Si j'ai bien compris les valeurs sont toutes comprises entre 0 et 10 et tu as un ensembles d'intervalles.
Si c'est forcément [0,2[, [2,4[ ... c'est très facile il suffit de faire un tableau à 5 cases. Mais comme on est des brutes on va faire ça dans le cas général. Et la première chose à faire puisqu'il est question d'intervalle, c'est de définir ce qu'est un intervalle :
#include <cassert>
class intervalle_t{
protected:
double min; // la borne min
double max; // la borne max
bool min_exclu; // la borne min est elle exclue ?
bool max_exclu; // la borne max est elle exclue ?
public:
// Le constructeur
intervalle_t(const double & min0=0,const double & max0=0,bool min_exclu0=false,bool max_exclu0=false):
min(min0),max(max0),
min_exclu(min_exclu0),max_exclu(max_exclu0)
{
assert(min<=max);
}
// Obtenir la borne inférieure
inline const double & get_min() const{
return min;
}
// Obtenir la borne supérieure
inline const double & get_max() const{
return max;
}
// Est ce que x est dans l'intervalle
inline bool contient(const double & x) const{
return (x > min || x >= min && !min_exclu) &&
(x < max || x <= max && !max_exclu);
}
};
Ok alors maintenant l'histogramme c'est juste un ensemble d'intervalle. Il faudra juste que tu contrôles que les intervalles forme une plage continue de valeurs, et qu'ils ne se recouvrent pas. Afin d'ordonner les intervalles (en priorité sur la borne min, ensuite sur la borne max), ce qui facilitera ce contrôle, je vais définir une relation d'ordre : inline bool operator<(const intervalle_t & i,const intervalle_t & j){
return (i.get_min() < j.get_min()) ||
(i.get_min() == j.get_min() && i.get_max() < j.get_max());
}
Il nous faut aussi un opérateur pour écrire un intervalle (<<). Tant qu'à faire je vais définir du même coup l'ecriture sur un std::ostream et un std::ofstream (en gros pour un fichier ou une sortie standard), et ceux à l'aide d'un template. Un template est en fait un type qui est remplacé à la compilation en fonction des besoins du programme. Une fonction template est toujours écrite intégralement dans le .hpp. template <typename Tstream>
Tstream & operator << (Tstream &,const intervalle_t i){
if (min_exclu) out << ']';
else out << '[';
out << min << ',' << max;
if (max_exclu) out << '[';
else out << ']';
return out;
}
A partir de maintenant on peut utiliser les std::set car l'operateur < a été défini. Là on a écrit le fichier intervalle.hpp, et on va passer maintenant à histogramme.hpp (un fichier par classe) #include "intervalle.hpp"
#include <set>
#include <map>
class histogramme_t{
protected:
std::map<intervalle_t,unsigned int> datas;
public:
// Le constructeur par défaut
histogramme_t(){}
//Un autre constructeur. A partir d'un ensemble d'intervalle je
// construit une map qui associe pour chaque intervalle le nb de pt
histogramme_t(const std::set<intervalle_t> & intervalles0){
const std::set<intervalle_t>::const_iterator
intervalle_it (intervalles0.begin()),
intervalle_end(intervalles0.end());
for(;intervalle_it!=intervalle_end;++intervalle_it){
const intervalle_t & intervalle = *intervalle_it;
datas[intervalle] = 0;
}
}
// Encore un constructeur (ici j'ai déjà ma map de point d'initialisée)
histogramme_t(const std::map<intervalle_t,unsigned int> & datas0):
datas(datas0)
{}
// Ajouter un point
void ajouter_point(const double & x){
std::map<intervalle_t,unsigned int>::iterator
data_it (datas.begin()),
data_end(datas.end());
for(;data_it!=data_end;++data_it){
const intervalle_t & intervalle = data_it->first;
if(intervalle.contient(x)) ++(data_it->second);
}
}
// Ecrire l'histogramme
template <typename Tstream>
Tstream & operator << (Tstream & out) const{
std::map<intervalle_t,unsigned int>::iterator
data_it (datas.begin()),
data_end(datas.end());
for(;data_it!=data_end;++data_it){
const intervalle_t & intervalle = data_it->first;
out << intervalle << " : ";
const unsigned int nb_etoile = data_it->second;
for(unsigned int i=0;i<nb_etoile;++i) out << '*';
out << std::endl;
}
return out;
}
};
Bon ben maintenant on à tout ce qu'il nous faut pour écrire main.cpp #include "intervalle.hpp"
#include "histogramme.hpp"
#include <iostream>
int main(){
// Construction des intervalles
std::set<intervalle_t> intervalles;
{
intervalles.insert(intervalle_t(0,2,false,true));
intervalles.insert(intervalle_t(2,4,false,true));
intervalles.insert(intervalle_t(4,6,false,true));
intervalles.insert(intervalle_t(6,8,false,true));
intervalles.insert(intervalle_t(8,10,false,true));
}
histogramme_t h(intervalles); // 2e constructeur
// Ajout des points
{
h.ajouter_point(1.1);
h.ajouter_point(6.9);
h.ajouter_point(2.8);
}
// Ecriture de l'histogramme
std::cout << h << std::endl;
return 0;
}
Bien spur comme il est tard je n'ai pas le temps de tester si tout ce que j'ai écrit marche mais c'est juste pour te donner une idée. Si tu as compris dans cet exemple à quoi servaient les iterator tu vas tout suite voir comment trouver l'intervalle qui a le plus ou le moins de valeur. Au besoin n'hésite pas à poser des questions si certains points dans le code te semblent peu clairs ou si tu ne vois pas comment faire Bonne chance |
le probleme c'est que je debute à peine le semestre 2 de L1 çà fait que tout ce que vous dites là je l'ai pas fait ...
On a juste appris à declarer des variables, le if le switch le while le do le for printf et scanf. On a aussi vu un peu les tableaux procedures et matrices et structures. On n'a pas encore fait les pointeurs... Donc ce serait que vous m'aidiez en utilisant ce que j'ai fait pour que je puisse comprendre. ce message s'adresse surtout à la derniere personne qui m'a repondu quand à la premiere le prog marche pas chez moi. Je vous remercie quand meme de votre aide. |
Oui alors effectivement si tu débutes ça ne va pas te convenir car apparemment tu n'as vu ni les classes, ni les référénces, ni les templates, ni les operator, ni la STL. Ca ne m'étonne pas que tu sois perdue !! En fait tu aurais dû mettre C dans le titre car tu n'as pas encore commencé à voir le C++.
Mais bon ce n'est pas très grave, si tu as vu les structures c'est presque pareil que les classes. Il faut définir une structure intervalle, une structure histogramme. Peux tu aussi nous dire si il y a forcément 5 intervalles et si ceux si on toujours un pas de 2 ? Ce genre d'informations permettrait de simplifier grandement le programme. Bonne chance
|
Je suis pas folle ya bien marqué C/C++ dans le sujet ? :-)
|
desole si j'ai fait uniquement du C et pas pas du C++ mais sur ma feuille de TP y a les deux donc bon o_O
Sinon dans l'exo 1 je ne dois pas utiliser de structures mais des fonctions et procedures maintenant si c'est plus simples avec des structures pourquoi pas pour le tableau c'est un tableau a 5 cases et apparemment il faut utiliser le "for" pour definir les intervalles avec ]2i,2(i+1)[ |
Oui les structures vont aider.
Je pense qu'il faut simplement que tu déclares un tableau de 5 cases, chaque case étant un intervalle (borne inf., sup. et sa valeur) : struct intervalle{
double inf, sup; // les bornes
int val; // la valeur
};
intervalle intervalles[5];
Une procédure pour initialiser les intervalles : void initialiser()
{
int i;
for(i = 0; i < 5; i++)
{
intervalles[i].inf = i * 2;
intervalles[i].sup = i * 2 + 1;
intervalles[i].val = 0;
}
}
Et une procédure pour y ajouter des réels : void saisir(double val)
{
int i;
for(i = 0; i < 5; i++)
{
if(val > intervalles[i].inf && val <= intervalles[i].sup)
{
intervalles[i].val++;
return;
}
}
// si on arrive ici, la valeur ne se range dans aucun intervalle
printf("Veuillez entrer un réel dans ]0.0;10.0]\n");
}
Une procédure pour afficher : void afficher()
{
int i, j;
for(i = 0; i < 5; i++)
{
printf("]%f,%f] : ", intervalles[i].inf, intervalles[i].sup);
for(j = 0; j < intervalles[i].val; j++)
printf("*");
printf("\n");
}
}
Une fonction pour le minimum : int minimum()
{
int i, imin, min = -1;
for(i = 0; i < 5; i++)
{
if(-1 == min || intervalles[i].val < min)
{
imin = i;
min = intervalles[i].val;
}
}
return imin;
}
Je te laisse faire celle du maximum :) |
J'aurais même mis des unsigned int :-)
Si on considère que ce sont forcément les intervalles [0,2[ [2,4[ ca me va en tout cas |
avec dev c++ çà marche pas =( |
Difficile de t'aider si tu n'en dit pas plus. Il faut au moins nous dire ce qui ne marche pas et quels sont les messages d'erreur.
Bonne chance |
subscripted value is neither array nor pointer |
c avec la premiere procedure que çà marche pas le premier intervalles provoque l'erreur citée plus haut |
J'ai compilé avec Dev c++ 4.9.9.2 et je n'ai aucune erreur à la compilation. (Enfin, j'avoue, j'ai trop trempé dans le C++ pour avoir oublié le "struct" devant les structures...)
Et il y avait aussi un chti bug à l'exécution (car je n'ai jamais testé le programme que j'ai écrit). Voici le code source complet :
/**
* @file plop.c
* @author plop!
* @date 03/02/07 05:30
* @brief Truc de N00b
*/
#include <stdio.h>
#include <windows.h>
struct intervalle{
double inf, sup; // les bornes
int val; // la valeur
};
struct intervalle intervalles[5];
void initialiser()
{
int i;
for(i = 0; i < 5; i++)
{
intervalles[i].inf = i * 2;
intervalles[i].sup = ( i + 1 )* 2;
intervalles[i].val = 0;
}
}
void saisir(double val)
{
int i;
for(i = 0; i < 5; i++)
{
if(val > intervalles[i].inf && val <= intervalles[i].sup)
{
intervalles[i].val++;
return;
}
}
// si on arrive ici, la valeur ne se range dans aucun intervalle
printf("Veuillez entrer un réel dans ]0.0;10.0]\n");
}
void afficher()
{
int i, j;
for(i = 0; i < 5; i++)
{
printf("]%f,%f] : ", intervalles[i].inf, intervalles[i].sup);
for(j = 0; j < intervalles[i].val; j++)
printf("*");
printf("\n");
}
}
int minimum()
{
int i, imin, min = -1;
for(i = 0; i < 5; i++)
{
if(-1 == min || intervalles[i].val < min)
{
imin = i;
min = intervalles[i].val;
}
}
return imin;
}
int main()
{
float in;
initialiser();
printf("Entrez des réels dans ]0;10] en terminant par 0\n");
while(1)
{
scanf("%f", &in);
if(in == 0) break;
saisir(in);
}
afficher();
//afficher ici les intervalles minimums et maximums
system("pause>nul");
return 0;
}
|
merci beaucoup de votre aide serieux vous roxxez maintenant me reste que le 3 lol
|
plop aide moiiiiiiiiiiiiiiiiiiiiiii! |
Ce que tu écris ne veux rien dire, je pense que là il faut relire ton cours de C, car ça ne sert à rien de te donner la solution direct si on veut que tu apprennes quelque chose. Par exemple :
- dans personneSalaire (une fonction) tu déclares une structure, mais cette structure devrait être déclarée à l'extérieur. - dans salaireSupSmic tu demandes à l'utilisateur de saisir des noms mais en fait il faudrait analyser la séquence de nom qu'il a déjà entrer et ressortir ceux qui ont un salaire (le scanf devrait par exemple fait dans une fonction saisie). Pour t'aider dans ton apprentissage - il faut écrire ton programme de manière très génériques (les fonctions appelées dans le main, qui définissent les grandes étapes), et ainsi de suite pour chaque étape, sous étape ou sous sous étape du programme. Par exemple dans ton cas 1) saisie 2) moyenne 3) supérieur au smic - Dans tout cas la structure la plus simple pour décrire un ensemble de salariés et de salaire est un truc du genre : typedef struct{
double salaires[TAILLE];
char noms[TAILLE][30]; // les noms sont de longueurs < 30
} salaries_t;
- Un exemple : la fonction moyenne devrait en toute rigueur se contenter de renvoyer un double (la moyenne) et l'affichage se fait depuis le main
#define TAILLE 30
...
double moyenne(double *tab,unsigned int taille){
unsigned int i;
double moyenne=0;
for(i=0;i<taille;++i) moyenne += tab[i];
moyenne /= taille;
return moyenne;
}
int main(){
salaries_t salaries;
... // remplissage de la structure
printf("Moyenne : %d\n",moyenne((double *) (salaries.salaires),TAILLE));
return 0;
}
Bonne chance |
Mon dieu tu veux la tuer
Je vois que tu ADORE les unsigned int :) Eh c'est marrant, je me suis assis sur mon pied et il est tout strillé (à cause du revêtement de la chaise) ! moyenne /= taille;est équivlent à moyenne = moyenne / taille;--------------------- printf("Moyenne : %d\n",moyenne((double *) (salaries.salaires),TAILLE));
est équivlent à double moy = moyenne((double *) (salaries.salaires), TAILLE);
printf("Moyenne : %d\n", moy);
Le (double *) sert à convertir le type de la variable salaries.salaires, car c'est un tableau de TAILLE cases, alors que la fonction prend en paramètre un tableau de n'importe quelle taille. (il faut savoir qu'un tableau est un pointeur vers le premier élément de ce tableau. Mais allons donc expliquer ce qu'est un pointeur à nuleninfo...) Pourquoi les filles sont nulles en info ?? Heureusement que mamiemando est là ! |
Bah c'est pas que j'adore les unsigned int... C'est juste que c'est un entier qui est toujours positif alors autant le préciser dans le programme :-) En plus quand tu compiles ça permet de récupérer des warnings intéressants :p |
| 27/10 00h37 | [PHP] Les ressemblances à ne pas confondre | PHP |
| 07/10 17h14 | Liste simplement chaînée | Langage C |
| 23/10 22h14 | Liste doublement chaînée | Langage C |
| 02/12 12h13 | Listes circulaires | Langage C |
| 07/12 20h32 | Les files | Langage C |
| 10/07 12h35 | Algorithme langage c et structure des données | 3 |
| 28/03 15h22 | [Langage C] Les structures ? | 5 |
| 24/03 16h28 | [borland c] fonction & structure | 5 |
| 13/11 00h39 | [XML] demande JUSTE confirmation de structure | 2 |
![]() | Easy Office - EasyOffice est une suite bureautique multilingue (Anglais et allemand seulement) possédant une interface graphique très... | Catégorie: Suite bureautique Licence: Freeware/gratuit |
![]() | Locate32 - Locate32 est un logiciel libre qui peut être employé pour rechercher les fichiers sur vos disques durs et d'autres... | Catégorie: Gestion de fichiers Licence: Freeware/gratuit |
![]() | Tab Catalog - Cette extension de Firefox apporte un petit confort visuel agréable: Les différents onglet apparaissent sous forme de... | Catégorie: Extensions Firefox Licence: Freeware/gratuit |
![]() | CCleaner - CCleaner (Crap Cleaner) est un utilitaire de nettoyage gratuit permettant de garantir un respect de la vie privée en... | Catégorie: Anonymat/Confidentialité Licence: Freeware/gratuit |
![]() | Sony CMT-CPZ2 | Catégorie: Chaîne Hi-Fi |