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 :

trouver le nombre de caractères différents dans un string


Sujet :

C++

  1. #1
    Membre régulier Avatar de fmh1982
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 93
    Points
    93
    Par défaut trouver le nombre de caractères différents dans un string
    bonjour

    mon problème est de trouver combien de caractères différents comporte un string exemple : "aab" 2 char différents "aaaabbbc" 3 char différents, j'ai essayé avec ce code mais le reésultat n'est pas toujours juste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for (int j=0; j<=chaine.size() ;j++)
    {	
    	if (chaine[chaine.size()] != chaine[j])
     
    	compteur +=1;		
     
     
    }
    Merci pour votre aide !!!

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Ce qui se passe, c'est que, déjà, chaine[chaine.size()] représente... l'équivalent du '\0'(le caractère représentant la fin de chaine en C)

    Au pire, tu devrait travailler sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for(unsigned int i=1;i<chaine.size();i++)
    {
        if(chaine[i]!=chaine[i-1])
            compteur++;
    }
    Mais cela poserait problème sur une chaine du genre "aaabbbbccccaab" qui te sortirait 5...

    Alors, ou bien, tu dois partir sur l'idée d'une boucle imbriquée, ou bien, il faut réfléchir à une autre solution...

    Et cette solution est fournie, directement, par la classe string...

    En effet, elle dispose de méthodes qui permettent de retrouver le premier (ou le dernier) caractère qui correspond (ou non) à un caractère d'une autre chaine (quatre méthodes au total)...

    Celle qui nous intéresse serait find_first_not_of(), qui nous permet de retrouver dans une chaine la position du premier caractère qui ne se trouve pas dans la chaine fournie en parametre

    Mais, pour cela, il faudra une chaine temporaire qui maintiendra les différents caractères trouvés

    Voici le code qui te permettra de faire ce que tu veux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    /** @str: chaine d'origine
        param: chaine contenant les caractères trouvés */
    std::string str="aaabbbbccccdddeeefffsssaaabcdef";
    std::string param="";
    // on boucle tant que l'on trouve dans str un caractère qui n'est pas dans
    // param
    while(str.find_first_not_of(param)!=std::string:npos)
        param+=str[str.find_first_not_of(param)];//ajoute le caractère trouvé
    //on affiche la liste des caractères uniques et la taille (qui correspond au
    // nombre de caractères uniques)
    std::cout<<param<<" "<<para.size()<<std::endl;
    provoquera la sortie
    Evidemment, rien ne t'empeche d'utiliser le principe pour en faire une fonction
    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

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Pour information, les quatre méthodes dont je parle sont:
    • str.find_first_of(param) qui permet de trouver la position du premier caractere de str qui se trouve dans param
    • str.find_first_not_of(param) qui est la méthode utilisée et qui trouve la position du premier caractère de str qui ne se trouve pas dans param
    • str.find_last_of(param) qui permet de trouver la position du dernier caractère de str à etre présent dans param
    • str.find_last_not_of(param) qui permet de trouver la position du dernier caractère de str à ne pas etre présent dans param
    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

  4. #4
    Membre régulier Avatar de fmh1982
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 93
    Points
    93
    Par défaut
    merci pour la rapidité , je vais essayer et je te redis ...........

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ce qui se passe, c'est que, déjà, chaine[chaine.size()] représente... l'équivalent du '\0'(le caractère représentant la fin de chaine en C)
    Pas vraiment non, c'est juste un débordement de capacité (rien de force un std::string à stocker son contenu sous forme de chaîne de type C).

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Laurent Gomila
    Pas vraiment non, c'est juste un débordement de capacité (rien de force un std::string à stocker son contenu sous forme de chaîne de type C).
    J'ai parlé d'équivalent... j'ai jamais dit que c'était réellement le cas...

    L'idée était surtout de faire comprendre ce que représente le size(), en prenant un exemple
    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

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Moi j'aurais bien vu une méthode bête et mèchante qui fonctionnerait aussi en C:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    std::string tachaine;
    bool tmp[256];
    for(size_t i=0;i<256;i++)
       tmp[i]=false;
    for(size_t i=0;i<tachaine.size();i++)
       tmp[(unsigned char)tachaine[i]]=true;
    int number=0;
    for(size_t i=0;i<256;i++)
       if(tmp[i]==true)
          number++;
    cout << number;
    Ce ne sera peut-être pas hyper rapide mais je ne pense pas que la solution à base de find_first_not_of() soit fort optimisée non plus.
    Par contre, ça n'est pas transformable en un algo générique qui pourrait aussi être utilisé pour gérer les wchar_t par exemple (ça occuperait bien trop de place sur la pile).
    Et pour ce qui est de l'utilisation de char, désolé mais pour moi le standard spécifie bien qu'un std::string doit utiliser le char comme type de caractère. Et une implémentation où un char ne fait pas exactement un octet j'attends de la voir (même si j'ai croisé je ne sais combien d'auteurs citant des trucs du style: "normalement un char correspond à un octet sur la plupart des implémentations").

  8. #8
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Si "aba" doit renvoyer 2, un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const int nb = std::set<char>(ch.begin(),ch.end()).size();
    suffit.

    Pour être plus rapide, utiliser un bool[numeric_limits<unsigned char>::max()] (je me méfie des accents, et c'est facile à adapter à un whar_t, bien qu'un peu cher en mémoire)
    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...

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Entre 256 bool et 16 000 000 sous windows il y a un monde de différence. Ne parlons même pas de linux avec ses wchar sur 4 bytes ce qui fera invariablement planter le programme.
    Mais de toutes façons, ta solution avec set est la meilleure.
    Au fait, c'est un détail mais cette syntaxe ne compilera pas, c'est pour ça que je préfère aller rechercher les constantes définies dans <climits> plutot que d'utiliser numeric_limit.

  10. #10
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Je sais très bien que la syntaxe ne compile pas
    Ceci dit, c'est vrai que parcourir une dixaine de milliers d'éléments pour trouver les non nuls, .... ce n'est pas terrible.
    std::set. Définitivement.
    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...

  11. #11
    Membre régulier Avatar de fmh1982
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 93
    Points
    93
    Par défaut
    Merci à tous ,, le code de koala01 fonctionne trés bien.... merci beaucoup...

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

Discussions similaires

  1. Réponses: 28
    Dernier message: 11/10/2006, 22h36
  2. Problème de nombre de caractères max dans Listbox
    Par jojoestpetit dans le forum Access
    Réponses: 1
    Dernier message: 09/04/2006, 11h39
  3. Nombre de valeurs différentes dans une colonne
    Par KrusK dans le forum Langage SQL
    Réponses: 4
    Dernier message: 24/08/2005, 14h18
  4. Réponses: 7
    Dernier message: 16/11/2004, 15h45
  5. URGENT - Nombre d'enregistrements différents dans une table
    Par Jeankiki dans le forum Bases de données
    Réponses: 6
    Dernier message: 11/08/2004, 15h51

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