Compter les occurrences de caractères dans une chaîne en C ++


199

Comment puis-je compter le nombre de "_"dans une chaîne comme "bla_bla_blabla_bla"?


17
@jdmichal: "question débutant mal posée"! = "devoirs"

@Roger: Bien sûr, ce n'est peut-être pas des devoirs, mais il est bon de supposer ses devoirs au moins pour les réponses, car 1) gâcher une question de devoirs est mauvais pour l'apprentissage, 2) vous pouvez toujours apprendre de bonnes "réponses aux devoirs", 3 ) l'OP peut (et devrait) donner son avis et dire que ce n'est pas un devoir
schnaader

3
@schnaader: Et si le PO dit que ce n'est pas ses devoirs, n'est-il pas encore probable que ce soit les devoirs de quelqu'un d'autre? Devrions-nous le «gâcher» pour eux? Et vice versa: une personne nouvelle en C ++ mais longtemps déscolarisée peut poser cette question; leur donneriez-vous une réponse "complète"? Pourquoi une caractéristique de l'affiche - attribuée par un enseignant (devoirs) - devrait-elle être une catégorisation du contenu de la question (balises)? Il semble que toutes les réponses ci-dessous, y compris la vôtre et la mienne, auraient été les mêmes quelle que soit cette balise.

@ Roger: J'aurais bien donné une autre réponse si j'étais sûr que ce ne sont pas des devoirs. Dans ce cas, j'avais répondu avec un code C complet au lieu d'un pseudocode. Et gâter d'autres personnes n'est pas si critique - s'ils peuvent le rechercher ici, ils peuvent également rechercher sur Google. En outre, la recherche de quelque chose pourrait en fait être une meilleure façon d'apprendre (bien que ce ne soit pas la meilleure) que de simplement publier vos devoirs et d'obtenir le code / les solutions complètes quelques minutes plus tard.
schnaader

2
@schnaader: Il y a 32 réponses et l'ordre de tri varie, laquelle? Pensez-vous que je n'aurais pas dû fournir une réponse «code complet» pour cette question «devoirs» ? Pour être tout à fait honnête, pour la question ici, il est utile d'encourager la réflexion indépendamment du fait qu'il s'agit de devoirs, et j'aime votre réponse beaucoup mieux que si elle avait un code C complet, pour cette raison. Vous êtes utile en répondant à la question et non à l' intention étrangère de l'affiche.

Réponses:


418
#include <algorithm>

std::string s = "a_b_c";
size_t n = std::count(s.begin(), s.end(), '_');

15
Le troisième argument est un type de caractère, c'est-à-dire un guillemet simple, pas un guillemet double ...
Emerson Xu

1
C'est la meilleure réponse.
Konchog

Petite note, mais le type de retour est généralement signé. Pour une raison quelconque, std::countrenvoie le type iterator_traits<InputIt>::difference_type, ce qui n'est std::ptrdiff_tpas le cas pour la plupart des conteneurs standard std::size_t.
Daniel Stevens

30

Pseudocode:

count = 0
For each character c in string s
  Check if c equals '_'
    If yes, increase count

EDIT: exemple de code C ++:

int count_underscores(string s) {
  int count = 0;

  for (int i = 0; i < s.size(); i++)
    if (s[i] == '_') count++;

  return count;
}

Notez que c'est du code à utiliser avec std::string, si vous utilisez char*, remplacez s.size()par strlen(s).

Notez également: je peux comprendre que vous souhaitiez quelque chose de "aussi petit que possible", mais je vous suggère d'utiliser cette solution à la place. Comme vous le voyez, vous pouvez utiliser une fonction pour encapsuler le code pour vous afin que vous n'ayez pas à écrire la forboucle à chaque fois, mais que vous pouvez simplement l'utiliser count_underscores("my_string_")dans le reste de votre code. L'utilisation d'algorithmes C ++ avancés est certainement possible ici, mais je pense que c'est exagéré.


24
Nous pouvons sûrement trouver une version de modèle totalement illisible avec des fonctions lamba et un appel à bind2nd ()?
Martin Beckett

@Martin, j'y pensais vraiment. Malheureusement, ma compréhension de la programmation fonctionnelle C ++ est pratiquement inexistante.
jdmichal

8
Je pense qu'appeler un service Web serait beaucoup plus amusant que les lambdas, alors l'algorithme de base n'est pas seulement impénétrable, il est stocké ailleurs.
Ben Voigt

Ce n'est pas une question de devoirs. Je suis nouveau en c ++ et je n'ai pas assez de connaissances en c ++ pour programmer cela de manière avancée. Lire: aussi petit que possible. Je suis capable de programmer cela d'une manière simple avec une boucle for et ainsi de suite, mais je cherchais une solution sophistiquée, quelque chose comme la solution de Diego. La prochaine fois, je donnerai plus d'informations pour la raison de la question.
andre de boer

En outre, vous souhaitez consommer des occurrences contiguës au cas où vous ne souhaiteriez pas de doublons. Comme par exemple, compter le nombre de pièces que vous obtiendrez après avoir divisé une chaîne par le caractère souhaité.
TheRealChx101

24

Solution à l'ancienne avec des variables nommées de manière appropriée. Cela donne au code un peu d’esprit.

#include <cstdio>
int _(char*__){int ___=0;while(*__)___='_'==*__++?___+1:___;return ___;}int main(){char*__="_la_blba_bla__bla___";printf("The string \"%s\" contains %d _ characters\n",__,_(__));}

Edit: environ 8 ans plus tard, en regardant cette réponse, j'ai honte de l'avoir fait (même si je me suis justifié comme un coup sarcastique à une question à faible effort). C'est toxique et pas correct. Je ne supprime pas le message; J'ajoute ces excuses pour aider à changer l'atmosphère sur StackOverflow. Alors OP: je m'excuse et j'espère que vous avez bien fait vos devoirs malgré ma pêche à la traîne et que des réponses comme les miennes ne vous ont pas découragé de participer sur le site.


1
Sérieusement? Une réponse délibérément obscurcie est la meilleure que vous puissiez faire et vous pensez qu'elle serait jamais appropriée ici?

4
@Tamas: int (true) vaut toujours 1 en C ++.

6
une solution vraiment à l'ancienne déclarerait un prototype pour sprintf au lieu de #inclure un fichier d'en-tête entier !
John Dibling

5
@Tamas: Bien sûr que non, mais je ne m'amuse pas en "répondant" aux questions des débutants.

11
Aimer. Dommage qu'il viole la règle du double soulignement.
Martin York

13
#include <boost/range/algorithm/count.hpp>

std::string str = "a_b_c";
int cnt = boost::count(str, '_');

10

Vous l'appelez ... Version Lambda ... :)

using namespace boost::lambda;

std::string s = "a_b_c";
std::cout << std::count_if (s.begin(), s.end(), _1 == '_') << std::endl;

Vous avez besoin de plusieurs inclusions ... Je vous laisse cela comme un exercice ...


7
Pensez-vous vraiment qu'un débutant va comprendre tout cela?
Josh Stodola

2
@Josh: Cela semble être une retombée du rire enfantin dans certains commentaires .

5
Certains des meilleurs programmeurs du monde ont passé les 15 dernières années à faire évoluer le C ++ au point où nous pouvons écrire ceci - ce n'est pas enfantin!
Martin Beckett

Faire valoir que ceux qui ne connaissent pas Perl sont obligés de le réinventer (mal) - maintenant ce serait puéril!
Martin Beckett

7
Il est ridicule de laisser de côté les inclusions.
PascalVKooten

5

L'utilisation de la fonction lambda pour vérifier que le caractère est "_", puis seul le nombre sera incrémenté sinon un caractère non valide

std::string s = "a_b_c";
size_t count = std::count_if( s.begin(), s.end(), []( char c ){if(c =='_') return true; });
std::cout << "The count of numbers: " << count << std::endl;

2
Veuillez ajouter une explication - essayez de ne pas publier uniquement des blocs de code simples.
CertainPerformance

1
Que pensez-vous, que votre réponse offre, quelle réponse précédente n'a pas déjà couverte? Veuillez modifier et développer votre réponse.
hellow

1
Merci pour cet extrait de code, qui pourrait fournir une aide immédiate limitée. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi il s'agit d'une bonne solution au problème et la rendrait plus utile aux futurs lecteurs ayant d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
Tim Diekmann

Utilisé la fonction lambda pour vérifier que le caractère est "_" alors seul le nombre sera incrémenté sinon pas un caractère valide.
Nagappa

[]( char c ){if(c =='_') return true; }invoque un comportement indéfini car vous n'avez pas renvoyé de valeur dans tous les chemins de code
phuclv

4

Il existe plusieurs méthodes de recherche de std :: string, mais find est probablement ce que vous recherchez. Si vous voulez dire une chaîne de style C, alors l'équivalent est strchr. Cependant, dans les deux cas, vous pouvez également utiliser une boucle for et vérifier chaque caractère - la boucle est essentiellement ce que ces deux terminent.

Une fois que vous savez comment trouver le personnage suivant à partir d'une position de départ, vous avancez continuellement votre recherche (c'est-à-dire utilisez une boucle), en comptant au fur et à mesure.


4

Compter les occurrences de caractères dans une chaîne est simple:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s="Sakib Hossain";
    int cou=count(s.begin(),s.end(),'a');
    cout<<cou;
}

1
-1 C'est la même chose que la première réponse existante de six ans plus tôt - qu'est-ce que cela voulait dire? Il y a une différence: cette réponse utilise le mauvais fichier d'en-tête. stdc ++. h est spécifique à GCC, et même avec ce compilateur, il est uniquement destiné à être utilisé dans les en-têtes précompilés.
Arthur Tacca


2

Vous pouvez trouver l'occurrence de '_' dans la chaîne source à l'aide des fonctions de chaîne. La fonction find () prend 2 arguments, la première chaîne dont nous voulons connaître les occurrences et le second argument prend la position de départ. Pendant que la boucle est utilisée pour trouver l'occurrence jusqu'à la fin de la chaîne source.

exemple:

string str2 = "_";
string strData = "bla_bla_blabla_bla_";

size_t pos = 0,pos2;

while ((pos = strData.find(str2, pos)) < strData.length()) 
{
    printf("\n%d", pos);
    pos += str2.length();
} 

2

J'aurais fait comme ça:

#include <iostream>
#include <string>
using namespace std;
int main()
{

int count = 0;
string s("Hello_world");

for (int i = 0; i < s.size(); i++) 
    {
       if (s.at(i) == '_')    
           count++;
    }
cout << endl << count;
cin.ignore();
return 0;
}

Oui bien sûr, et en fait je l'ai fait, mais je sais à quel point cela a gâché quand je l'ai copié de Visual Studio vers SO.
Shivam Jha

0

J'aurais fait quelque chose comme ça :)

const char* str = "bla_bla_blabla_bla";
char* p = str;    
unsigned int count = 0;
while (*p != '\0')
    if (*p++ == '_')
        count++;

-3

Essayer

#include <iostream>
 #include <string>
 using namespace std;


int WordOccurrenceCount( std::string const & str, std::string const & word )
{
       int count(0);
       std::string::size_type word_pos( 0 );
       while ( word_pos!=std::string::npos )
       {
               word_pos = str.find(word, word_pos );
               if ( word_pos != std::string::npos )
               {
                       ++count;

         // start next search after this word 
                       word_pos += word.length();
               }
       }

       return count;
}


int main()
{

   string sting1="theeee peeeearl is in theeee riveeeer";
   string word1="e";
   cout<<word1<<" occurs "<<WordOccurrenceCount(sting1,word1)<<" times in ["<<sting1 <<"] \n\n";

   return 0;
}

-4
public static void main(String[] args) {
        char[] array = "aabsbdcbdgratsbdbcfdgs".toCharArray();
        char[][] countArr = new char[array.length][2];
        int lastIndex = 0;
        for (char c : array) {
            int foundIndex = -1;
            for (int i = 0; i < lastIndex; i++) {
                if (countArr[i][0] == c) {
                    foundIndex = i;
                    break;
                }
            }
            if (foundIndex >= 0) {
                int a = countArr[foundIndex][1];
                countArr[foundIndex][1] = (char) ++a;
            } else {
                countArr[lastIndex][0] = c;
                countArr[lastIndex][1] = '1';
                lastIndex++;
            }
        }
        for (int i = 0; i < lastIndex; i++) {
            System.out.println(countArr[i][0] + " " + countArr[i][1]);
        }
    }

1
Oups! Mauvaise langue.
Courses de légèreté en orbite
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.