IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

[Debutant] Calcul de mediane d'un vecteur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Par défaut [Debutant] Calcul de mediane d'un vecteur
    Bonjour à tous;
    je desire calculer la valeur mediane d'un vecteur (ou d'un tableau). Alors j'ai écrit le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    void CalculMediane(float *tab, int nb_ech, float *mediane, float *max, float *min)
     
    {	
       *mediane=0.0;
        *max=0.0;
        *min=0.0;
    	int i,per=1;
    	float tmp;
    	while (per == 1)
    	{
    		per = 0;
    		for (i=0; i<nb_ech; i++)
    		{
    			if (tab[i] > tab[i+1])
    			{
    				tmp = tab[i];
    				tab[i] = tab[i+1];
    				tab[i+1] = tmp;
    				per = 1;
    			}
    		}
    	}
     
    	*min = tab[0];
    	*max = tab[nb_ech-1];
    	*mediane = (tab[nb_ech/2 -1] + tab[nb_ech/2])/2;
    	//Attention : cas d'un tableau contenant n = 2*k echantillons;
     
    }
    Ce code me permet de calculer la valeur mediane d'un tableau. Mon problème est que je manipule des données et j'ai besoin de supprimer certaines valeurs comme ce qui suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     vector<double> tabs0;
     for (int j=0;j<257;j++)
    		 {
    			 if(lignebase[j]!=0)
    			 {
    				 tabs0.push_back(lignebase[j]);
     
    			 }
    		 }
    Je voudrais calculer la valeur mediane de mon nouveau vecteur comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     float  mediane, M, m;
    CalculMediane(tabs0,tabs0.size(),&mediane,&M,&m);
    A la compilation, j'obtiens une erreur "no matching function for call to CalculMediane(......)";

    Merci pour votre aide;

  2. #2
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Tu as toutes les fonctions qu'il faut dans <algorithm>.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Par défaut
    J'ai été sur le forum algorithme mais je n'ai pas trouvé un exemple qui puisse me débloquer.

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Je n'ai jamais fait allusion au forum "algorithmes", mais au fichier d'en-tête standard <algorithm> (d'où les chevrons) -> http://r0d.developpez.com/articles/algos-stl/
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Membre averti
    Inscrit en
    Avril 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 21
    Par défaut
    salut,

    redéfini calculMediane avec un vector<double> &, plutôt qu'un pointeur sur un float, et le compilateur te trouvera une correspondance. Et tant qu'à faire, tu pourrais même utiliser la fonction "sort" de algorithm, au lieu t'embéter :

    http://www.cplusplus.com/reference/algorithm/sort.html

  6. #6
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Même std::sort, c'est s'embêter quand on peut directement accéder au N/2 i-ème.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    L'un des grands avantages du C++, c'est qu'il permet de renvoyer une valeur en sortie des fonctions...

    Du coup, les arguments sont à considérer, en priorité, comme des données entrantes (des données nécessaires à la fonction pour qu'elle puisse faire son travail).

    Il ne faut en effet considérer de créer des arguments "in/out" que si tu n'as vraiment pas le choix (que les modifications apportées à plusieurs "objets" dans une fonction doivent être répercutées dans la fonction appelante)

    De plus, le C++ fournit la possibilité d'utiliser des références, qui sont largement plus faciles à utiliser que les pointeurs.

    Du coup, il est également préférable de choisir de passer les arguments in/out sous forme de référence non constante plutôt que sous forme de pointeurs, à moins que l'on n'ait de nouveau pas le choix.

    Tu peux donc simplifier la signature de ta fonction sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float CalculMediane(float *tab, int nb_ech,float &max, float &min)
    En effet, le code que tu fournis semble indiquer que tu veux garder la valeur correcte non seulement de la médiane, mais également du minimum et du maximum...

    Mais le fait d'utiliser des références te permet d'écrire le code exactement comme s'il s'agissait, pour min et max, de réels tout ce qu'il y a de plus classiques, et donc de t'éviter les problèmes liés au déréférencement et à l'utilisation de "l'adresse de la variable".

    L'appel de la fonction devenant alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float mediane=CalculerMediane(tabs0,tabs0.size(),M,m);
    (tu ne trouves pas cela plus simple )

    Enfin, il faut quand même se rappeler que le C++ est un langage orienté objet, et qu'il semblerait peut être opportun de réfléchir à une conception sous cette forme (mais ca, c'est un autre débat )

    Mais, même en ne considérant pas l'orientation objet du C++, ne crois tu pas qu'il serait opportun de travailler avec des structures "qui vont bien", dont une qui regrouperait les informations obtenues lors du calcul de la médiane (le minimum, le maximum et la médiane, en l'occurrence), qui ressemblerait par exemple à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct MinMaxMed
    {
        float min; // le minimum
        float max; // le maximum
        float med; // la médiane
        /*juste "pour le fun" */
        MinMaxMed(float min, float max, float med):min(min), 
                 max(max),med(med){}
    };
    et qui te permettrait encore de simplifier la signature de la fonction sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MinMaxMed CalculerMediane(float*tab,int size)
    (c'est encore mieux, non )

    Dont l'implémentation prendrait alors la forme de (en prenant en compte l'existence du type booléen, qui fournit uniquement les valeur true et false
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    MinMaxMed CalculerMediane(float*tab,int size)
    {
        /* on commence par trier le tableau */
        bool permutation=true; /* j'aime bien les noms de variables qui me disent
                               * précisément ce qu'elles font :D
                               */
        while (permutation==true)
        {
            permutation=false;
            for(int i=0;i<size+1;++i)
            {
                if(tab[i]<tab[i+1])
                {
                    double tmp=tab[i+1];
                    tab[i+1]=tab[i];
                    tab[i]=tmp;
                    permutation=true;
                } 
            }
        }
        return MinMaxMed(tab[0],tab[size-1],(tab[nb_ech/2 -1] + tab[nb_ech/2])/2);
    }
    et qui pourrait alors être appelée sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    float *tab=NULL;
    int size = 10;
    tab= new float[size];
    /*...*/
    MinMaxMed result=CalculerMediane(tab, size);
    Maintenant, étant donné que tu décide d'utiliser la classe vector, tu peux même encore simplifier la signature sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MinMaxMed CalculerMediane(std::vector<float>& tab);
    dont l'implémentation prendrait en compte le fait que la classe vector connait le nombre d'éléments qu'elle contient et qui fera que l'appel devienne tout simplement de l'ordre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector<float> myVector;
    /*...*/
    MinMaxMed result=CalculerMediane(myVector)
    (n'est-ce pas là le rafinement suprême )

    Et, bien sur, comme l'ont sussuré les autres, tu devrais aller faire un petit tour du côté du fichier d'en-tête <algorithm> (et de l'article de rüd qui le concerne )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Et pour parfaire, on remplace tous les int devant faire office d'indexes ou de taille de tableaux par des size_t.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Et pour parfaire, on remplace tous les int devant faire office d'indexes ou de taille de tableaux par des size_t.
    De fait...

    Disons que ca, c'est vraiment pour parfaire une fois que l'on utilise la classe vector...

    Dans les autres cas, c'est moins nécessaire (quoi que cela puisse être utile, sur les tableaux particulièrement important )

    En fait, je ne voulais pas *trop* modifier l'existant quand meme (je l'ai déjà fait un sérieux coup )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 106
    Par défaut
    Merci beaucoup pour votre aide. En effet cette fonction fait partie d'une classe. L'idée de la structure est très interssante mais je ne sais pas exactement où la placer (avant la declaration de la classe je pense); voilà ce que je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #include <vector>
    using namespace std;
    #ifndef DETECTION_H_
    #define DETECTION_H_
     
    struct MinMaxMed
    {
        float min; // le minimum
        float max; // le maximum
        float med; // la médiane
        MinMaxMed(float min, float max, float med):min(min), 
                 max(max),med(med){}
    };
    class Detection
    {
    public:
     
    	void highpass(float *sig,float *sigfiltre, double *h,int nbech, int ncoef);
    	void EnvelopEnergie(float *sigin, float *sigOut, int n);	
    	void seuillage(float *sigin,float *sigSeuille,float *ligneBase, float seuil,int taille);	
      MinMaxMed CalculerMediane(float *tab,int size);
    };
     
    #endif /*DETECTION_H_*/
    en suivant vos indications, je fais l'implémentation de la méthode comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    float Detection::CalculerMediane(vector<double> &tab,int size)
    {
        /* on commence par trier le tableau */
        bool permutation=true; /* j'aime bien les noms de variables qui me disent
                               * précisément ce qu'elles font :D
                               */
        while (permutation==true)
        {
            permutation=false;
            for(int i=0;i<size+1;++i)
            {
                if(tab[i]<tab[i+1])
                {
                    double tmp=tab[i+1];
                    tab[i+1]=tab[i];
                    tab[i]=tmp;
                    permutation=true;
                } 
            }
        }
        return MinMaxMed(tab[0],tab[size-1],(tab[size/2 -1] + tab[size/2])/2);
    Je n'arrive pas à compiler: erreur"candidate is: MinMaxMed Detection::CalculerMediane(std::vector<float, std::allocator<float> >&, int)"

    Je ne sais pas exactement ce qu'il faut faire;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. calcul de la mediane d'un vecteur
    Par karaudrey88 dans le forum R
    Réponses: 2
    Dernier message: 02/04/2012, 13h54
  2. Réponses: 5
    Dernier message: 31/08/2006, 20h39
  3. [Débutant] Calcul dans un rapport
    Par manu_port dans le forum Access
    Réponses: 2
    Dernier message: 24/07/2006, 21h52
  4. [debutant] calcul d'âge.
    Par Mathusalem dans le forum Oracle
    Réponses: 2
    Dernier message: 25/03/2006, 14h47
  5. [Debutant]calcul de valeurs propres, givens-householder
    Par malbarre dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 18/08/2005, 16h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo