Buchstabenpaare in string finden



  • Hallo, ich suche nach einer Funktion oder einem eleganten Weg in einem

    string s;
    

    bei einem eingelesenen Wort Buchstabenpaaren zu finden, dh zB 2 gleiche Buchstaben. Ich habe da schon einiges ausprobiert, funktioniert aber erstens nicht und sieht zweitens alles furchtbar umständlich (==kompliziert==fehleranfällig) aus, ich denke dass <string> selber da sehr elegante Lösungen dazu liefern müssten, weiss aber nicht welche, evtl weiss das jemand von Euch? 😞



  • Mein erster Gedanke wäre

    std::string::iterator find_2_consecutive_chars(std::string s) {
      std::string::iterator i = s.begin(), j = s.begin();
      for(++j; j != s.end() && *i != *j; ++i, ++j);
      return j == s.end()? s.end() : i;
    }
    


  • hm, interessant !
    Die Funktion gibt allerdings direkt aufeinanderfolgende Paare zurück(hatte ich ja auch gefragt, aber blöderweise nicht gemeint, damit man besser erraten kann was ich eigentlich fragen wollte, melde ich mich hiermit nochmal) 🙂

    Aber danke trotzdem, die Funktion geht hoffentlich trotzdem in mein Wissen mit ein, wenn ich sie mal so brauchen sollte.

    Ich hab mich blöd ausgedruckt, sorry. Mein Problem ist, zB im String "Orangensaft", die Anzahl doppelter Buchstaben zu finden, also hier 2 Paare, da je 2 mal 'a' und 'e'. N-tschuldigung, da ich vorher in Eile war hab ich mich dumm ausgedrückt.



  • Hm, ein schnellschuss wäre eine map zu missbrauchen:

    #include <map>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <functional>
    using namespace std;
    
    void mycount(char  c,std::map<char,unsigned int>  * m) 
    {(*m)[c]++;}
    
    void ausgabe(pair<char,unsigned int> t)
    {cout<<t.first<<" kommt "<<t.second<<"mal vor\n";}
    
    bool mehrals(pair<char,int> t,unsigned int i)
    {return t.second<i;}
    
    int main()
    {
    	std::string temp;
    	cout<<"Gib was ein\n";
    	getline(cin,temp);
    
    	std::map<char,unsigned int> countmap;
    	for_each(temp.begin(),temp.end(),bind2nd(ptr_fun(mycount),&countmap));
    
    	for_each(countmap.begin(),countmap.end(),ausgabe);
    
    	for(map<char,unsigned int>::iterator i = countmap.begin();i != countmap.end();)
    	{if(mehrals(*i,2))
    		countmap.erase(i++);
    	 else
    		++i;
    	}
    
    	cout<<"\n\n";
    	for_each(countmap.begin(),countmap.end(),ausgabe);
    
    }
    


  • Danke,
    hat mir weitergeholfen ! Hab das zurechtschnitzen können für die Prog-Afg, ein paar Fragen hätte ich da aber doch noch dazu:

    @Oxdeadbeef:
    Deine Funktion zählt nur das erste "Paar", oder? Hab sie nicht getestet, aber mir ist aufgefallen, dass ja die Schleife abbricht, nachdem das erste "Paar" gefunden wurde?

    @Knuddlbaer:
    Wofür bindest Du denn <algorithm> ein, oder warum reicht <functional> nicht auch?

    Weshalb baust Du denn diese Zeile ein:

    bind2nd( ptr_fun( mycount),&countmap)
    

    Ich hab gelesen, dass es sich dabei um eine Pointer-to-Funktion-Conversion handelt, weiss aber nicht genau was das ist/wann das nötig ist (sollte ich da evtl neu posten?)

    Ich kann mir denken, dass das zum einbringen der Werte des Strings in eine Map nötig ist, aber gibts da keinen einfacheren (ausgeschriebenen) Weg? (naja ist ja eigentlich zumindest recht kurz)

    Wie bekommt denn "ausgabe" in

    for_each(countmap.begin(),countmap.end(),ausgabe);
    

    zu seinem Parameter, dem pair<> ?

    😕



  • in algorithm ist for_each deklariert:

    // TEMPLATE FUNCTION for_each
    template<class _II, class _Fn> inline
    	_Fn for_each(_II _F, _II _L, _Fn _Op)
    	{for (; _F != _L; ++_F)
    		_Op(*_F);
    	return (_Op); }
    

Anmelden zum Antworten