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 :

Fonction find et classe vector


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 3
    Par défaut Fonction find et classe vector
    Bonjour les amis,

    Je dispose d'un vecteur rempli de 100 pris au hasard entre 0 et 10 (entier) et je dois utiliser la fonction "find" pou obtenir la liste des indices associés dans le vector à la valeur 5.
    Voilà ce que j'ai fais pour l'instant :

    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
    31
    32
    33
    34
    35
    36
    37
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    #include <numeric>
    using namespace std;
     
     
     
     
    int main()
    {
    	vector<int> v(100,1);
    	//v.clear();
    	cout<<v.size()<<endl;
    	vector<int>::iterator it;
    	srand(time(NULL));
    	for(int i(0);i<100;i++)
    	{
    		v[i]=rand()%11;
    	}
    	cout<<" "<<endl;
    	for(int i(0);i<100;i++)
    	{
    		cout<<v[i]<<endl;
    	}
    	cout<<" "<<endl;
    	it=find(v.begin(),v.end(),5);
    	cout<<*it<<endl;
     
    	return 0;
     
     
    }
    Le problème c'est que le it telle qu'elle me pointe sur la valeur 5 mais je n'arrive pas à avoir l'indice du premier élément valant 5. Ensuite je pense que je dois faire une boucle pour trouver tous les indices mais je n'y arrive pas.

    Merci d'avance pour votre aide.
    Cordialement

    Généréal Shermann.

  2. #2
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    Bonjour,

    Tout d'abord quelques conseils.
    1- déclare toujours tes variables au dernier moment dans ton code. Nous ne sommes pas en C mais en C++. Donc ton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<int>::iterator it;
    tu dois le déclarer juste avant son utilisation.
    2 - Même si à l'école on apprend ça Ne le fait jamais. Préfères mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    using::cout; 
    using::endl;
    et mieux juste mettre "std::" devant chaque appelle de fonction std, et ce pour des questions de lecture du code ( on sait tout de suite que c'est une fonction standard que l'on appelle si on la voit avec "std::" devant.
    3- Chippotage mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(unsigned int i = 0;i<100;++i)
    est plus propre que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(int i(0);i<100;i++)
    mais ici c'est plus l'expérience qui parle que le bon fonctionnement de ton application.

    Sinon,

    Un iterateur n'est pas un index! C'est comme un pointeur qui va allez vers l'avant ou vers l'arrière voir les deux(pas en même temps bien-sur). Donc tu ne peux pas avoir ton index avec un iterateur sauf en utilisant l’arithmétique des pointeurs ( regardes sur internet pour en savoir plus -> petit début ici ).
    Dans ton cas, pour obtenir les index, tu dois utiliser l'index de ta boucle for.
    Tu parcours ton vecteur, tu compares et si c'est bon tu affiches le "i" de ton vecteur c'est l'index dans ton vecteur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(int i = 0;i<100;++i)
    {
        if(v[i] == 5)
            cout<< i <<endl;
    }

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 3
    Par défaut
    Tout d'abord merci de ta réponse.

    Ensuite merci pour les conseils de syntaxe mais il faut savoir que je ne fais pas vraiment de la programmation pour faire de l'informatique poussé. ca n'a peut-être pas d'importance mais je suis en Mathématiques (M1) et mon but est de faire avant tout des algorithmes qui marchent, je dois avouer qu'on ne fait pas trop attention à la syntaxe et au moment de déclaration des variables en calcul scientifique.

    Pour ta méthode pour afficher les indices j'y avais penser mais le prof veut qu'on utilise la fonction find et c'est là que les difficultés commencent.

  4. #4
    Membre chevronné
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Par défaut
    Déjà, pour les itérateurs sur un vector, si tu veux le convertir en indice tu peux faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::distance(v.begin(), it);
    Sinon, pour trouver toutes les occurrences, tu faire ainsi:
    Tu initialise ton itérateur à begin().
    Tant qu'il est différent de end()
    tu fais une recherche (avec find) entre it + 1 et end()

    Après, libre à toi de faire des choses avec ces itérateurs/indices à chaque tours

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 146
    Billets dans le blog
    4
    Par défaut
    Bonsoir

    je ne vois pas ce que veut que vous fassiez votre professeur. std::find retourne un itérateur vers un élément qui contient la valeur cherchée, il ne sert pas à compter ou trouver tous les éléments qui ont cette valeur.

    Ou bien avec un code de ce style, loin d'être idéal notament pour sa relecture pas évidente:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    it = vec.begin();
    iterator found;
    while ((found = std::find(it, vec.end(), valeur) != vec.end())
    {
     std::cout<<"found : "<<it<<std::endl;
     it = found;
    }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2012
    Messages : 21
    Par défaut
    Salut,
    juste histoire de préciser (surtout si tu fais des algos à vocation scientifique), rand est à éviter pour des distributions uniformes (voir le talk de STL ici)

    Voici un bout de code rapide qui devrait faire ce que tu souhaites (C++11 needed )

    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
    #include <iostream>
    #include <algorithm>
    #include <random>
    #include <vector>
    #include <chrono>
     
    int main() {
     
    	auto seed1 = std::chrono::system_clock::now().time_since_epoch().count();
    	std::mt19937 mt(seed1);
    	std::uniform_int_distribution<int> dist(0,10);
    	auto gen = std::bind(dist,mt);
     
    	std::vector<int> vec(100);
    	int to_find = 5;
    	int cpt = 0;
     
    	std::generate(vec.begin(),vec.end(),gen);
     
    	std::for_each(vec.begin(),vec.end(),[&](int it){if (it == to_find) std::cout << "5 found : " << cpt << std::endl; ++cpt;});
     
    	return 0;
    }

  7. #7
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 868
    Par défaut
    Donner la solution directement c'est plutôt moyen. Tant qu'a faire t'aurais aussi pu la rendre plus lisible.

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2012
    Messages : 21
    Par défaut
    salut,

    C'était plus histoire d'illustrer une solution avec une distribution uniforme que de résoudre son problème (qui avait déjà des solutions au dessus).
    Par contre ça m’intéresse de savoir ce que tu trouves peu lisible dans ce code ?

  9. #9
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 868
    Par défaut
    Les solutions proposees au-dessus ne donnaient pas une solution complete (sauf erreur de ma part). C'est dommage de donner une solution toute faite a quelqu'un car ca veut dire qu'au final il aura plus de mal a refaire ca la fois suivante que quelqu'un ayant trouve la solution lui-meme (aide ou non, ca n'a pas d'importance).

    Pour la lisibilite c'etait juste un petit detail : dans ton appel a std::for_each. Je trouvais juste que passer l'adresse d'une fonction ecrite plus haut aurait rendu la lecture plus simple.

  10. #10
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Par défaut
    Moi j'aurais utilisé un std::map et j'aurais simulé des incides

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	map<int, int> m;  // Le premier pourrais être ton chiffre rand() et le deuxième ton indice
    	map<int, int>::iterator it;
    	for(int i(0);i<100;i++)
    	{
    		m[rand()%11]=i;
    	}
    	cout<<" "<<endl;
    	for(it = m.begin();it!=m.end();it++)
    	{
    		cout<<it->first<<endl;
    	}
    	cout<<" "<<endl;
    	it=m.find(5);
    	cout<<it->seconde<<endl;

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut,
    Citation Envoyé par moham104 Voir le message
    Moi j'aurais utilisé un std::map et j'aurais simulé des incides

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	map<int, int> m;  // Le premier pourrais être ton chiffre rand() et le deuxième ton indice
    	map<int, int>::iterator it;
    	for(int i(0);i<100;i++)
    	{
    		m[rand()%11]=i;
    	}
    	cout<<" "<<endl;
    	for(it = m.begin();it!=m.end();it++)
    	{
    		cout<<it->first<<endl;
    	}
    	cout<<" "<<endl;
    	it=m.find(5);
    	cout<<it->seconde<<endl;
    ouchhh quelle horreur!!! Mais il est fou!!!

    Cela revient, ni plus ni moins, à sortir un bazooka pour essayer de tuer une mouche

    On peut, décemment, s'interroger sur la raison qui pousse ton prof à vouloir te faire utiliser la fonction find, qui renvoie un itérateur, au lieu de baser directement ta logique sur les indexes, ce qui serait quand même beaucoup plus simple.

    Ceci dit, comme il a déjà été dit, il existe la fonction distance qui permet de récupérer le nombre d'élément entre deux itérateurs, et qui se paye même le luxe d'être en temps constant lorsque les deux itérateurs sont issus d'un tableau

    1. Par contre, la "meilleure" façon d'obtenir toutes les valeurs consiste à :
    2. prendre l'itérateur sur le début du tableau comme point de départ
    3. utiliser l'itérateur obtenu comme premier paramètre de la fonction find (le deuxième étant toujours l'itérateur matérialisé par la fonction end() du tableau)
    4. puis, tant que l'itérateur renvoyé par find n'est pas égal à l'itérateur renvoyé par la fonction end() du tableau:
    5. calculer l'index de l'itérateur obtenu grâce à la fonction std::distance
    6. introduire l'index obtenu dans la collection ad-hoc
    7. recommencer en 3
    TIP: il faut donc créer une boucle qui ne soit pas une boucle "pour" pour avoir la certitude de bel et bien lister l'ensemble des éléments recherchés
    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

  12. #12
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,
    ouchhh quelle horreur!!! Mais il est fou!!!
    Je suis daccord avec ce que vous dite, mais même l'utilisation d'un vector pour 100 élément est exagéré. Pour 100 élément j'aurais bien utilisé un tableau de int.

    Je crois que pour un débutant ce qui est important c'est d'avoir un résultat fonctionnel et de découvrir différent approche au problème. J'ai donné ma réponse en ayant cette idée en tête.

    Mais merci quand même pour la remarque.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Citation Envoyé par moham104 Voir le message
    Je suis daccord avec ce que vous dite, mais même l'utilisation d'un vector pour 100 élément est exagéré. Pour 100 élément j'aurais bien utilisé un tableau de int.

    Je crois que pour un débutant ce qui est important c'est d'avoir un résultat fonctionnel et de découvrir différent approche au problème. J'ai donné ma réponse en ayant cette idée en tête.
    Avoir un résultat fonctionnel est une chose, avoir un résultat qui tienne un minimum la route en est une autre

    Si l'on peut déjà très largement se demander quel objectif le prof poursuit en demandant de travailler avec la fonction find, on peut malgré tout espérer qu'il a une raison bien précise de le faire.

    Mais, si ta logique n'est pas fausse en soi, il faut reconnaitre qu'elle représente une complexité supplémentaire totalement inutile.

    Or, la solution la plus simple est toujours la meilleure (du moins, jusqu'à preuve du contraire).

    Le prof demande déjà de relier Bruxelles à Paris en passant par Berlin, soit, mais toi, tu conseilles en plus de passer par Stockholm et Vladivostok !

    Tu reconnaitras que, même s'il est possible de le faire de la sorte, il y a quand même beaucoup plus simple
    Mais merci quand même pour la remarque.
    Crois bien que mon intention n'était certainement pas de te vexer d'une quelconque manière.

    La manière dont j'ai réagi par écrit correspondait simplement à la réaction épidermique que j'ai eue en lisant ton intervention.

    Si tu t'es senti attaqué par ma remarque, je t'en fais mes plus plates excuses.
    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

Discussions similaires

  1. fonction find et vector ? [c++]
    Par panthere noire dans le forum Débuter
    Réponses: 6
    Dernier message: 29/07/2010, 10h27
  2. [MFC/Excel] Fonction Find de la classe CRange
    Par SmOkEiSBaD dans le forum MFC
    Réponses: 1
    Dernier message: 02/06/2008, 10h03
  3. [Excel/Range] Fonction Find de la classe CRange
    Par SmOkEiSBaD dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 02/06/2008, 10h02
  4. fonction de la classe vector ?
    Par ricault dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 26/04/2007, 14h21
  5. "class" vector à indice variable et fonction membr
    Par icetechnik dans le forum C++
    Réponses: 14
    Dernier message: 25/11/2005, 23h46

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