Wie Anzahl ermitteln?
-
Ja, ginge auch, du müsstest nur eine andere Vergleichsfunktion an count_if() übergeben:
struct string_match { string_match(const string& data) : m_data(data) {} bool operator()(const string& wert) { return wert.find(m_data) != string::npos; } private: string m_data; }; ... cout<<count_if(...,string_match("xxxx"));
-
CStoll schrieb:
Ja, ginge auch, du müsstest nur eine andere Vergleichsfunktion an count_if() übergeben
Na,ja vor allen darf man keine std::string's also Worte, die durch Whitespace Chars von einander getrennt sind, einlesen. Wenn man den count_if beibehalten möchte, bedarf es einer eigenen Klasse, die solange Zeichenfolgen liest, bis was passendes daher kommt. Etwa so
#include <iostream> #include <fstream> #include <string> #include <algorithm> // count_if #include <iterator> // istream_iterator #include <functional> // bind2nd, equal_to struct Zeichenfolge { explicit Zeichenfolge( const std::string& txt = std::string() ) : m_txt( txt ) {} bool operator==( const Zeichenfolge& b ) const { return m_txt == b.m_txt; } friend std::istream& operator>>( std::istream& in, Zeichenfolge& zf ) { const std::ios_base::fmtflags oldFlags = in.flags(); in >> std::noskipws; std::string txt; char c = 0; for( std::string::iterator iMuster = Zeichenfolge::m_muster.begin() ; iMuster != Zeichenfolge::m_muster.end() && in >> c; ++iMuster ) { txt.append( 1, c ); if( c != *iMuster ) break; } in.flags( oldFlags ); if( in ) swap( zf.m_txt, txt ); return in; } static void SetMuster( const std::string& muster ) { m_muster = muster; } private: std::string m_txt; static std::string m_muster; }; std::string Zeichenfolge::m_muster; int main() { using namespace std; const string muster = "xxxx"; ifstream datei( "input.txt" ); Zeichenfolge::SetMuster( muster ); cout << "Der Ausdruck '" << muster << "' ist " << count_if( istream_iterator< Zeichenfolge >( datei ), istream_iterator< Zeichenfolge >(), bind2nd( equal_to< Zeichenfolge >(), Zeichenfolge( muster ) ) ) << " mal enthalten" << endl; return 0; }Die Lösung über die statische Variable ist eigentlich nicht so toll; spätestens bei Multithreading funktioniert das nicht mehr. Schöner wäre es, den Muster-String via Manipulatoren und ios_base::pword an den istream zu hängen, aber das bläht den Code weiter auf.
Ich vermute aber mal, dass das ganze mit boost::regex oder so einfacher zu lösen ist.
Gruß
Werner
-
dixidix schrieb:
...Mit den beiden letzten Funktionen kommt nur 0 als Rückgabe!
... was auch vollkommen klar ist, wen man den Code versteht.

dixidix schrieb:
...
hsdgxxxx jhaxxxxsjdh sjaf kasjdfkjw xxxxmsdgh kjdf lwjkrxxxxfhlkwe grfadxxxx lejkrek xxxxashg...
sollen eigentlich
hsdgxxx xjhaund
x x xxauch mitgezählt werden ?
Das ist eben genau das, was ich meinte: Du musst für Dich klären, was genau Du möchtest - das ist eine fachliche Entscheidung. Keine der Varianten ist "besser" als die anderen, sondern höchstens "passender".
Außerdem würde ich Dir raten, die verschiedenen hier angebotenen Lösungen mal genau zu studieren und zu versuchen sie zu verstehen - dann kannst Du es vielleicht noch "passgenauer" programmieren.
Gruß,
Simon2.
-
So wie es jetzt ist also "xxxx" finden/zählen ist schon ok. Mir wäre sicher auch was eingefallen, aber sicher nicht so und anhand von solchen Beispielen lässt sich doch einiges besser nachvollziehen. Insofern wieder mal Danke!!

-
Schade, ich habe gerade festgestellt, dass mein zuletzt geposteter Code nicht für beliebige Mustertexte funktioniert. Z.B. findet er den Ausdruck 'Hallo' in
irgendwas HalHallo ..
nicht. Lässt sich zwar reparieren, aber ich habe jetzt keine Zeit ...
Gruß
Werner
-
emmax schrieb:
Ich würde die gesamte Datei in einen Puffer einlesen und dann mit der Funktion memcmp() mir die Anzahl der Vorkommen holen in einer Schleife holen.
PS: memcmp() hat C++ von C geerbt.

Hier mal mein Code
#include <cstring> #include <fstream> #include <iostream> using namespace std; int main () { ifstream file ("input.txt", ios::binary | ios::ate); streamsize len = file.tellg (); char* buf = new char [len]; file.seekg (0, ios::beg); file.read (buf, len); file.close (); const char muster[] = "xxxx"; int zähler = 0; for (streamsize i = 0; i < len; i++) { if (!memcmp (buf+i, muster, (sizeof muster)-1)) { zähler++; i += (sizeof muster)-2; } } delete[] buf; cout << muster << " kommt " << zähler << " mal vor." << endl; } ;)
-
dixidix schrieb:
So wie es jetzt ist also "xxxx" finden/zählen ist schon ok. Mir wäre sicher auch was eingefallen, aber sicher nicht so und anhand von solchen Beispielen lässt sich doch einiges besser nachvollziehen. Insofern wieder mal Danke!!

Noch was: Was soll bei
xxxxxrauskommen ? 0, 1, 2 ?
Gruß,
Simon2.
-
Simon2 schrieb:
Noch was: Was soll bei
xxxxxrauskommen ? 0, 1, 2 ?
Gruß,
Simon2.
1
... zähler++; i += (sizeof muster)-2; // Lesen! ...
-
emmax schrieb:
Simon2 schrieb:
Noch was: Was soll bei
xxxxxrauskommen ? 0, 1, 2 ?
Gruß,
Simon2.
1
... zähler++; i += (sizeof muster)-2; // Lesen! ...
Du kannst die Frage danach, was fachlich gewünscht ist, nicht mit einer Eigenschaft Deiner spezifischen Implementierung beantworten.
Gruß,
Simon2.
-
Öhm ... mein Code soll 0 zurückgeben? Oha ^^ Der macht es sogar möglich, dass der auch erkennt, wenn der Text in der nächsten Zeile weiter geht. Also er lässt das Newline außer acht.