Suche via std::search innerhalb meiner Klasse und weiteren Suchoptionen



  • Hi, danke erstmal für Deine Antwort!

    Ich kannte Funktoren bisher nicht und habe mich mal schlau gemacht (-> http://www.cpp-tutor.de/cpp/le18/le18_03.htm)... .
    Also wenn ich das richtig verstanden habe, bringen die mich aber nicht weiter.

    Hier mal ein (Pseudo-)Code, der mein Problem verdeutlicht:

    class A
    {
        std::string str;
        bool casesense;
    
        static bool compare1(char s1, char s2)
        { return (s1 == s2); }
        bool compare2(char s1, char s2) const
        {
             if(this->casesense) // Problem, da this ja nur ohne static geht, std::search aber ne Funktion erwartet.
                return (toupper(s1) == toupper(s2));
             else
                return (s1 == s2);
        }
    
        public:
          int suche(const std::string& what) const
          {
             std::string::const_iterator i = std::search(str.begin(), str.end(), what.begin(), what.end(), compare1);
             if(i == str.end())
                return -1;
             else
                return i - str.begin();
          }
    }
    

    Wenn ich im obrigen Code nun compare2 an std::search statt compare1 übergebe, gibts Compilier-Fehler. Wie kann ich nun meine compare2-Methode (anstatt der (statischen) compare1-Funktion) übergeben, sodass ich innerhalb der Vergleichsfunktion, die ja von std::search aufgerufen wird, auf den this-Zeiger zugreifen kann?

    Ich habe auch schon Interessantes aus dem Header <functional> wie z.B. mem_fun_ref gefunden, aber irgenwie löst das mein Problem nicht, auch wenn vllt. die Richtung stimmt 😃 .

    Auf jeden Fall danke für Deine/eure Bemühungen! 👍



  • Mir fällt grad nochwas ein (hat aber damit nicht direkt zu tun): Gibt es eine search-Methode, die wie std::string::rfind von hinten nach vorne sucht? Habe im Header <algorithm> keine gefunden (oder übersehen?)... 😕

    PS: Beim Vertauschen der Iteratoren bei std::search gibts ne Assertion mit "invalid iterator range...". Das habe ich schon ausprobiert.



  • Warum machst du da ne static Memberfunction? Mach die unabhängig von der Klasse und füge dort halt ne funktion, wie isCaseSense hinzu. Dann kannst du das ganz einfach machen.

    Du kannst ja rbegin und rend brauchen, um von hinten nach vorne zu arbeiten.



  • Hm, aber in einer (unabhängigen) Funktion kann ich doch auch nicht auf den this-Zeiger zugreifen...oder wie meinst Du das? Also diese Methode "suche", die die Funktion std::search verwendet ist halt an eine Klasse gebunden und das was durchsucht wird ("str") ebenfalls (und das soll auch so bleiben^^).

    Wie würdest Du denn eine solche Funktion deklarieren? 😉

    thx!



  • class compare
    {
    	bool Casesense;
    public:
    	explicit compare (bool b):Casesense(b){}
    
    	bool operator () (const char c1, const char c2)
    	{
    		if(Casesense)
    			return (toupper(c1) == toupper(c2));
    		else
    			return (c2 == c2);
    	}
    };
    
    class A
    {    
        std::string str;
        bool casesense;
    
    public:
    	int suche(const std::string& what) const
    	{
    		std::string::const_iterator i = std::search(str.begin(), str.end(), what.begin(), what.end(), compare (casesense) );
    		if(i == str.end())
    			return -1;
    		else
    			return i - str.begin();
    	}
    };
    

    Jetzt mal rein allgemein gesehen. Ich würde das ganze Design wahrscheinlich anders machen. 😉 Kommt halt auf die Anforderungen an.



  • Wuhuuuu, ich werd verrückt, das funktioniert 🙂 - tausend Dank! Genau das, hab' ich gesucht 🙂 !

    Dann hab ich damit noch ein Problemchen:

    Du kannst ja rbegin und rend brauchen, um von hinten nach vorne zu arbeiten.

    Die Methoden geben alle einen 'reverse_iterator' zurück. Die Funktion std::search erwartet aber einen Forward-Iterator und anscheinend sind die auch nicht kompatibel (Compiler beschwert sich^^).

    Nochmal danke, hast mir echt weitergeholfen! 👍



  • Ich weiss zwar nicht, was du genau erreichen willst, aber es gibt da ja auch noch std::find.
    Damit kannst du das sehr viel einfacher machen, was wir bis jetzt haben. 😉

    class A
    {    
        std::string str;
        bool casesense;
    
    public:
        int suche(const std::string& what) const
        {
            return str.find (what.c_str());
        }
    };
    

    Der Rückgabewert für nicht gefunden ist jetzt einfach std::string::npos

    Schau sonst mal hier rein:
    http://www.cplusplus.com/reference/string/string/find.html

    Da findest du bestimmt das,wonach du suchst. Und wenn nicht, dann schau nochmal hier nach:
    http://www.cplusplus.com/reference/algorithm/

    Und wenn du dann immernoch nicht das passende gefunden hast, schreibst du was eigenes. Und wenn du das dann nicht hinkriegst mit deiner genauen Vorstellung nochmal posten. 😉

    Ich persönlich tippe einfach mal ins Blaue, dass du std::string::find_first_of() suchst. Jetzt musst du diese Funktion nur noch einsetzen (was nicht allzu schwer ist).



  • Öhm, ne die Methoden bzw. Links sind mir bekannt nur so einfach ist die Sache leider net^^.

    Ich will das, was std::string::rfind macht, effizient nachprogrammieren bzw. suche dafür eine Funktion alá std::search (was ja äquivalent zu std::string::find ist). Der einfach Grund für das Vorhaben ist (u.a.), dass rfind bzw. find keine Wildcards unterstützen 😉 .


  • Mod

    search gibt einen zum ersten Argumentpaar passenden Iterator zurück. Sind diese Iteratoren reverse-Iteratoren gilt das entsprechend auch für den Rückgabewert. Dann muss der Rest des Codes entsprechend angepasst werden:

    int suche(const std::string& what) const
        {
            std::string::const_reverse_iterator i = std::search(str.rbegin(), str.rend(), what.begin(), what.end(), compare (casesense) );
            return str.rend() - i - 1;
        }
    

    oder man geht zum jeweiligen Element gehörigen normalen Iterator zurück.

    int suche(const std::string& what) const
        {
            std::string::const_iterator i = std::search(str.rbegin(), str.rend(), what.begin(), what.end(), compare (casesense) ).base();
            return i - str.begin() - 1;
        }
    

    Für Faule gibt es natürlich auch noch string::find&co



  • Für Faule gibt es natürlich auch noch string::find&co

    Was hast das mit faul zu tun, wenn man die Algorithmen nimmt, die auf das Problem passen? (Auch wenn das hier jetzt nicht der Fall ist)

    Ich schreibe ja auch nicht jedesmal, wenn ich etwas sortieren will den Algorithmus neu.. 🙄



  • Jo danke, nach Deinen tausend Edit's funktionierts jetzt 😃 .

    Aber bzgl.:

    camper schrieb:

    Für Faule gibt es natürlich auch noch string::find&co

    ...haste Dir mal meinen vorletzten Post durchgelesen? ➡ Anscheinend *nicht*...

    Auch nochmal @drakon danke! 😉


Anmelden zum Antworten