Zählen Sie das Auftreten von Zeichen in einer Zeichenfolge in C ++

198

Wie kann ich die Anzahl "_"in einer Zeichenfolge wie zählen "bla_bla_blabla_bla"?

andre de boer
quelle
17
@jdmichal: "schlecht gestellte Anfängerfrage"! = "Hausaufgaben"
@ Roger: Natürlich sind es vielleicht keine Hausaufgaben, aber es ist gut, zumindest für die Antworten die Hausaufgaben anzunehmen, denn 1) das Verwöhnen einer Hausaufgabenfrage ist schlecht zum Lernen, 2) man kann immer noch aus guten "Hausaufgabenantworten" lernen, 3 ) Das OP kann (und sollte) Feedback geben und sagen, dass dies keine Hausaufgabe ist
Schnaader
3
@schnaader: Was ist, wenn das OP sagt, dass dies nicht ihre Hausaufgaben sind, ist es wahrscheinlich nicht immer noch Hausaufgaben für jemand anderen? Sollen wir es ihnen "verderben"? Und umgekehrt: Jemand, der neu in C ++ ist, aber lange nicht zur Schule gegangen ist, kann diese Frage stellen. Würden Sie ihnen eine "vollständige" Antwort geben? Warum sollte ein Merkmal des Posters - das von einem Lehrer zugewiesen wird (Hausaufgabe) - eine Kategorisierung des Inhalts der Frage (Tags) sein? Es scheint, als wären alle Antworten unten, einschließlich Ihrer und meiner, unabhängig von diesem Tag gleich gewesen.
@ Roger: Ich hätte in der Tat eine andere Antwort gegeben, wenn ich sicher wäre, dass dies keine Hausaufgaben sind. In diesem Fall hatte ich mit vollständigem C-Code anstelle von Pseudocode geantwortet. Und andere Leute zu verwöhnen ist nicht so wichtig - wenn sie hier danach suchen können, können sie auch Google durchsuchen. Außerdem ist die Suche nach etwas möglicherweise eine viel bessere (wenn auch nicht die beste) Möglichkeit, etwas zu lernen, als nur Ihre Hausaufgaben zu veröffentlichen und einige Minuten später vollständigen Code / Lösungen zu erhalten.
Schnaader
2
@schnaader: Es gibt dort 32 Antworten und die Sortierreihenfolge variiert, welche? Glaubst du, ich hätte keine "vollständige Code" -Antwort für diese "hausaufgabenähnliche" Frage geben sollen ? Um ganz ehrlich zu sein, ist es für die Frage hier hilfreich, zum Nachdenken anzuregen, unabhängig davon, ob es sich um Hausaufgaben handelt, und ich mag Ihre Antwort aus diesem Grund viel besser, als wenn sie einen vollständigen C-Code hätte. Sie sind hilfreich, indem Sie auf die Frage antworten , nicht auf die fremde Absicht des Posters.

Antworten:

417
#include <algorithm>

std::string s = "a_b_c";
size_t n = std::count(s.begin(), s.end(), '_');
Benoit
quelle
15
Das dritte Argument ist ein Zeichentyp, dh ein einfaches Anführungszeichen, kein doppeltes Anführungszeichen ...
Emerson Xu
1
Dies ist die beste Antwort.
Konchog
Kleiner Hinweis, aber der Rückgabetyp ist normalerweise signiert. Aus irgendeinem Grund std::countzurückkehrt Typ iterator_traits<InputIt>::difference_type, die für die meisten Standard - Container ist std::ptrdiff_t, nicht 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: C ++ Beispielcode:

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

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

  return count;
}

Beachten Sie, dass dieser Code gemeinsam zu verwenden , um mit std::string, wenn Sie verwenden char*, ersetzen Sie s.size()mit strlen(s).

Beachten Sie auch: Ich kann verstehen, dass Sie etwas "so klein wie möglich" wollen, aber ich würde Ihnen empfehlen, stattdessen diese Lösung zu verwenden. Wie Sie sehen, können Sie den Code mithilfe einer Funktion für Sie kapseln, sodass Sie die forSchleife nicht jedes Mal ausschreiben müssen, sondern nur count_underscores("my_string_")den Rest Ihres Codes verwenden können. Die Verwendung fortgeschrittener C ++ - Algorithmen ist hier sicherlich möglich, aber ich denke, es ist übertrieben.

Schnaader
quelle
24
Sicherlich können wir eine völlig unlesbare Vorlagenversion mit Lamba-Funktionen und einem Aufruf von bind2nd () entwickeln?
Martin Beckett
@ Martin Ich habe tatsächlich darüber nachgedacht. Leider ist mein Verständnis der funktionalen C ++ - Programmierung praktisch nicht vorhanden.
jdmichal
8
Ich denke, ein Webdienst aufzurufen würde viel mehr Spaß machen als Lambdas. Dann ist der Kernalgorithmus nicht nur unergründlich, sondern wird an anderer Stelle gespeichert.
Ben Voigt
Dies ist keine Hausaufgabenfrage. Ich bin neu in C ++ und habe nicht genug Kenntnisse in C ++, um dies auf fortgeschrittene Weise zu programmieren. Lesen Sie: so klein wie möglich. Ich kann dies auf einfache Weise mit einer for-Schleife usw. programmieren, aber ich suchte nach einer ausgeklügelten Lösung, so etwas wie der Lösung von Diego. Nächstes Mal werde ich weitere Informationen zum Grund der Frage geben.
andre de boer
Außerdem möchten Sie zusammenhängende Vorkommen konsumieren, falls Sie keine Duplikate möchten. Zählen Sie beispielsweise, wie viele Teile Sie erhalten würden, nachdem Sie eine Zeichenfolge durch das gewünschte Zeichen geteilt haben.
TheRealChx101
24

Altmodische Lösung mit entsprechend benannten Variablen. Dies gibt dem Code etwas Geist.

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

Bearbeiten: Ungefähr 8 Jahre später, als ich mir diese Antwort anschaue, schäme ich mich, dass ich das getan habe (obwohl ich es mir selbst als snarky stupsen bei einer Frage mit geringem Aufwand gerechtfertigt habe). Das ist giftig und nicht in Ordnung. Ich entferne den Beitrag nicht. Ich füge diese Entschuldigung hinzu, um die Atmosphäre in StackOverflow zu verändern. Also OP: Ich entschuldige mich und hoffe, dass Sie trotz meines Trolling Ihre Hausaufgaben richtig gemacht haben und dass Antworten wie meine Sie nicht davon abgehalten haben, an der Website teilzunehmen.

Tamás Szelei
quelle
1
Ernsthaft? Eine absichtlich verschleierte Antwort ist das Beste, was Sie tun können, und Sie denken, dass dies hier jemals angemessen wäre?
4
@Tamas: int (true) ist in C ++ immer 1.
6
Eine wirklich altmodische Lösung würde einen Prototyp für sprintf deklarieren, anstatt eine ganze Header-Datei einzuschließen !
John Dibling
5
@Tamas: Natürlich nicht, aber ich habe keinen Spaß daran, Anfängerfragen zu "beantworten".
11
Liebe es. Schade, dass es gegen die doppelte Unterstrichregel verstößt.
Martin York
13
#include <boost/range/algorithm/count.hpp>

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

Sie nennen es ... Lambda-Version ... :)

using namespace boost::lambda;

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

Du brauchst mehrere Includes ... das überlasse ich dir als Übung ...

Diego Sevilla
quelle
7
Glaubst du wirklich, dass ein Neuling irgendetwas davon verstehen wird?
Josh Stodola
2
@ Josh: In einigen Kommentaren scheint es ein Nebeneffekt des kindlichen Lachens zu sein .
5
Einige der weltbesten Programmierer haben die letzten 15 Jahre damit verbracht, C ++ so weit zu entwickeln, dass wir dies schreiben können - es ist nicht kindisch!
Martin Beckett
Es ist klar, dass diejenigen, die Perl nicht kennen, gezwungen sind, es (schlecht) neu zu erfinden - das wäre jetzt kindisch!
Martin Beckett
7
Es ist lächerlich, die Includes wegzulassen.
PascalVKooten
5

Wenn Sie die Lambda-Funktion verwenden, um zu überprüfen, ob das Zeichen "_" ist, wird nur die Anzahl erhöht, andernfalls wird kein gültiges Zeichen verwendet

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;

Nagappa
quelle
2
Bitte fügen Sie eine Erklärung hinzu - versuchen Sie nicht, nur einfache Codeblöcke zu veröffentlichen.
Bestimmte Leistung
1
Was denkst du, was deine Antwort bietet, was eine vorherige Antwort noch nicht behandelt hat? Bitte bearbeiten und erweitern Sie Ihre Antwort.
Gelb
1
Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte und sofortige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
Tim Diekmann
Verwendet die Lambda-Funktion, um zu überprüfen, ob das Zeichen "_" ist. Dann wird nur die Anzahl erhöht, andernfalls kein gültiges Zeichen.
Nagappa
4

Es gibt verschiedene Methoden von std :: string für die Suche, aber find ist wahrscheinlich das, wonach Sie suchen. Wenn Sie eine Zeichenfolge im C-Stil meinen, ist das Äquivalent strchr. In beiden Fällen können Sie jedoch auch eine for-Schleife verwenden und jedes Zeichen überprüfen. Die Schleife ist im Wesentlichen das, was diese beiden zusammenfassen.

Sobald Sie wissen, wie Sie das nächste Zeichen an einer Startposition finden, setzen Sie Ihre Suche fort (dh verwenden Sie eine Schleife) und zählen dabei.


quelle
4

Das Zählen von Zeichen in einer Zeichenfolge ist einfach:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s="Sakib Hossain";
    int cou=count(s.begin(),s.end(),'a');
    cout<<cou;
}
Md. Sakib Hossain
quelle
1
-1 Dies ist das Gleiche wie die bestehende Top-Antwort von vor sechs Jahren - was sollte dies hinzufügen? Es gibt einen Unterschied: Diese Antwort verwendet die falsche Header-Datei. stdc ++. h ist spezifisch für GCC und selbst mit diesem Compiler nur für die Verwendung in vorkompilierten Headern vorgesehen.
Arthur Tacca
4
Empfohlene Lektüre: Warum sollte ich <bits / stdc ++. H> nicht # einschließen?
Leichtigkeitsrennen im Orbit
2

Sie können das Auftreten von '_' in der Quellzeichenfolge mithilfe von Zeichenfolgenfunktionen ermitteln. Die Funktion find () verwendet zwei Argumente: den ersten String, dessen Vorkommen wir herausfinden möchten, und das zweite Argument die Startposition. Während der Schleife wird das Vorkommen bis zum Ende des Quellstrings ermittelt.

Beispiel:

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();
} 
Amruta Ghodke
quelle
2

Ich hätte es so gemacht:

#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;
}
Shivam Jha
quelle
Ja natürlich, und tatsächlich habe ich das getan, aber ich weiß nicht, wie es durcheinander kam, als ich es von Visual Studio in das SO-Formular kopiert habe.
Shivam Jha
0

Ich hätte so etwas gemacht :)

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

Versuchen

#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;
}
Software Designer
quelle
-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]);
        }
    }
Pramod
quelle
1
Hoppla! Falsche Sprache.
Leichtigkeitsrennen im Orbit