was macht diese Funktion?



  • Hallo!

    Kann jemand so nett sein und mir diese FUnktion hier auskommentieren, also was wo genau passiert? Danke.



  • int suche(char *stringA, char *stringB) // String A = Suchstring, String B = zu durchsuchender String
    {
    	char *x = stringA; // String A sichern, da er verändert wird
    
    	while (*stringB) // String B bis zum Ende laufen lassen
    	{
    		if ((*stringB++ & ~0x20) == (*stringA & ~0x20)) // Vergleich der Zeichen (Groß- und Kleinschreibung ist egal)
    		{
    			if (!*++stringA) // Suchstring A ist zu ende => String B enthält String A
    			{
    				return 1; // Etwas gefunden
    			}
    		} 
    		else
    		{
    			stringA = x; // Nichts gefunden, also Suchstring zurücksetzen und von vorne durchlaufen
    		}
    	}
    
    	return 0; // Nichts gefunden
    }
    

    Der Code ist jedenfalls eine absolute Katastrophe. Da wollte jemand besonders coolen Code schreiben und hat damit besonders schlechten Code abgeliefert. Wo auch immer du das her hast, es ist ein echtes Negativbeispiel! Außerdem ist es kein C++, sondern C. 👎



  • Danke!
    Ich hab das in der Tat irgendwie via Google gefunden und blicke im Prinzip null durch was da passiert...
    Wie würdest du das denn einfacher lösen?


  • Mod

    Da du das Problem ja anscheinend nur gelöst haben willst anstatt es von Hand zu Programmieren, nimm eine gute Bibliothek:
    http://www.boost.org/doc/libs/1_46_0/doc/html/string_algo.html

    Konkret die Funktion boost::icontains.

    Da Boost quelloffen ist, kannst du dir auch dort den Quellcode ansehen. Wobei Boostcode in der Regel recht schwer zu lesen ist.



  • doch doch, ich würde sehr gerne von hand was in c++ programmieren.


  • Mod

    Eine nicht effiziente, aber einfache, Idee: Transformiere zunächst beide Zeichenketten nach nur Groß- oder nur Kleinschreibung. Dann benutzt du die Standardsuchalgorithmen.



  • #include <string>
    #include <iostream>
    #include <algorithm>
    
    size_t suche(std::string input, std::string search)
    {
    	std::transform(input.begin(), input.end(), input.begin(), toupper);
    	std::transform(search.begin(), search.end(), search.begin(), toupper);
    
    	return input.find(search);
    }
    
    int main()
    {
    	std::string A = "Hallo Welt und so...";
    	std::string B = "welt";
    
    	size_t pos;
    	if ((pos = suche(A, B)) != std::string::npos)
    	{
    		std::cout << "Gefunden: " << A.substr(pos) << "\n";
    	}
    	else
    	{
    		std::cout << "Nicht gefunden!\n";
    	}
    
    	return 0;
    }
    

    Simpel.



  • jhkhjk schrieb:

    Außerdem ist es kein C++, sondern C. 👎

    Das sehe ich jetzt nicht. Ist es nicht eher sowohl C als auch C++?

    jhkhjk schrieb:

    #include <string>
    #include <iostream>
    #include <algorithm>
    
    size_t suche(std::string input, std::string search)
    {
    	std::transform(input.begin(), input.end(), input.begin(), toupper);
    	std::transform(search.begin(), search.end(), search.begin(), toupper);
    
    	return input.find(search);
    }
    
    int main()
    {
    	std::string A = "Hallo Welt und so...";
    	std::string B = "welt";
    
    	size_t pos;
    	if ((pos = suche(A, B)) != std::string::npos)
    	{
    		std::cout << "Gefunden: " << A.substr(pos) << "\n";
    	}
    	else
    	{
    		std::cout << "Nicht gefunden!\n";
    	}
    
    	return 0;
    }
    

    Simpel.

    Wenn das C++ ist, dann mag ich es irgendwie nicht.



  • Und dann auch noch ernstgemeinte Beiträge löschen und nicht mal auf die berechtigten(!) Fragen anderer Forenteilnehmer eingehen. Das ist so arm! 👎

    Du bist es _NICHT_



  • Rogi schrieb:

    Kann jemand so nett sein und mir diese FUnktion hier auskommentieren (...)

    Ich bin mir sicher dass das vielen von euch durch den Kopf gegangen ist beim Lesen dieser Frage, daher ...:

    /*
    int suche(char *stringA, char *stringB)
    {
    char *x = stringA;
    
    while (*stringB){
    if ((*stringB++ & ~0x20) == (*stringA & ~0x20)){
    if (!*++stringA)
    return 1;
    } else
    stringA = x;
    }
    return 0;
    }
    */
    

    🤡



  • @hustbaer: lol

    Hier ein Weg, wie man auch nicht zu viel überlegen muß, aber nicht vorher transformiert werden muß:

    struct CaseInsesitiveCharCompare{
        bool operator()(char a,char b){
            return std::toupper(a)==std::toupper(b);
        }
    };
    
    size_t suche(std::string input, std::string search){
        std::string::iterator pos=std::search(input.begin(),input.end(),search.begin(),search.end(),CaseInsesitiveCharCompare());
        if(pos==input.end())
            return std::string::npos;
        return pos-input.begin();
    }
    


  • Wieso hast du hier ein strcut genommen, und nicht gleich eine Funktion geschrieben?



  • Struktur schrieb:

    Wieso hast du hier ein strcut genommen, und nicht gleich eine Funktion geschrieben?

    Also das hier:

    bool CaseInsesitiveCharCompare(char a,char b){
        return std::toupper(a)==std::toupper(b);
    }
    
    size_t suche(std::string input, std::string search){
        std::string::iterator pos=std::search(input.begin(),input.end(),search.begin(),search.end(),&CaseInsesitiveCharCompare);
        if(pos==input.end())
            return std::string::npos;
        return pos-input.begin();
    }
    

    Weil die struct quasi garantiert, daß der Vergleich inline gemacht wird, denn für search<...,CaseInsesitiveCharCompare> muß neuer Code gebastelt werden. search weiß dann genau, welche Vergleichsfunktion ich verwende und kann inlinen.

    Beim Funktionszeiger wird search<...,bool(*)(char,char)> verwendet und die Info, welche Vergleichsfunktion genommen wird, erfährt search erst zur Laufzeit. Es ist zu füchten, daß dann ein Funktionsaufruf über den Funktionszeiger gemacht wird und nicht inline. Außer er optimiert ganz schlau.



  • jhkhjk schrieb:

    std::transform(input.begin(), input.end(), input.begin(), toupper);
        std::transform(search.begin(), search.end(), search.begin(), toupper);
    

    Das ist aus drei Gründen problematisch: Du bindest <cctype> nicht ein, toupper befindet sich im Namensraum std, und es kann sich, wenn die ersten beiden Probleme beseitigt sind, mit toupper aus <locale> beißen.

    Wie dem auch sei, wenn wir schon über C++ vs. C sprechen, dann finde ich, es wäre guter Stil, sich nicht an die alte C-Locale zu binden. Ich schlage Folgendes vor:

    #include <algorithm>
    #include <locale>
    #include <iostream>
    #include <string>
    
    class ci_compare {
    public:
      ci_compare(std::locale const &loc = std::locale()) : loc_(loc) { }
    
      inline bool operator()(char c, char d) const {
        return std::tolower(c, loc_) == std::tolower(d, loc_);
      }
    
    private:
      std::locale loc_;
    };
    
    std::string::size_type isuche(std::string const &haystack,
                                  std::string const &needle,
                                  std::locale const &loc = std::locale()) {
      std::string::const_iterator pos = std::search(haystack.begin(), haystack.end(),
                                                    needle  .begin(), needle  .end(),
                                                    ci_compare(loc));
    
      return pos != haystack.end() ? pos - haystack.begin() : std::string::npos;
    }
    


  • Das erinnert mich an Iterators Must Go 🙂

    Warning sign #2 schrieb:

    File copy circa 1975:

    #include <stdio.h>
    int main() {
      int c;
      while ((c = getchar()) != EOF)
        putchar(c);
      return errno != 0;
    }
    

    Fast forward 20 years, and. . .

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <string>
    using namespace std;
    
    int main() {
      copy(istream_iterator<string>(cin),
      istream_iterator<string>(),
      ostream_iterator<string>(cout,"\n"));
    }
    

    (forgot the try/catch around main)

    Something, somewhere, went terribly wrong.



  • Nexus schrieb:

    Das erinnert mich an Iterators Must Go 🙂

    Warning sign #2 schrieb:

    File copy circa 1975:

    #include <stdio.h>
    int main() {
      int c;
      while ((c = getchar()) != EOF)
        putchar(c);
      return errno != 0;
    }
    

    Fast forward 20 years, and. . .

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <string>
    using namespace std;
    
    int main() {
      copy(istream_iterator<string>(cin),
      istream_iterator<string>(),
      ostream_iterator<string>(cout,"\n"));
    }
    

    (forgot the try/catch around main)

    Something, somewhere, went terribly wrong.

    HAHAHAHAHAA^^ ders gut 😃


Log in to reply