tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
4
ZUGRIFFE
253
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
  1. #1
    engelmarkus engelmarkus ist offline Mitglied Brokat
    Registriert seit
    Sep 2007
    Beiträge
    473
    Hier habe ich eine Lösung in C++ geschrieben.
    Wie in der VB.Net-Lösung sind auch hier zwei Dateien im Projekt, in einer die einfache Lösung, in der anderen die Lösung mit Erweiterung.
    Angehängte Dateien Angehängte Dateien
     

  2. #2
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.800
    Blog-Einträge
    5
    Hallo,

    könntest du in Zukunft den Quelltext direkt in den Beitrag schreiben? Danke.

    Meine Anmerkungen:
    • Wenn du C++ verwendest, warum verzichtest du dann auf den Einsatz von std::string?
    • Zum Durchlaufen der Vektoren wäre es vielleicht besser, einen Iterator zu verwenden.
    • Zu jedem new gehört ein delete! Solange das Programm nach der Erledigung seiner Aufgabe sofort terminiert, ist das kein allzu großes Problem, allerdings sollte man sich trotzdem eine korrekte Speicherverwaltung angewöhnen.
    • Gibt es einen speziellen Grund, warum Daten und Ergebnisliste Zeiger sind?

    Grüße,
    Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  3. #3
    engelmarkus engelmarkus ist offline Mitglied Brokat
    Registriert seit
    Sep 2007
    Beiträge
    473
    Danke erstmal für die Verbesserungsvorschläge. Ich muss ganz ehrlich gestehen, dass ich den Code nicht in einer "geistigen Umnachtung" geschrieben hab, sondern einfach C++ nicht sonderlich gut kann .
    Deswegen kann ich dir deine Fragen auch nicht beantworten, ich habs jetzt einfach mal entsprechend umgebaut:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <vector>
     
    // Hier werden die Zeilen aus der Datei abgelegt
    std::vector<std::string> Daten;
     
    int main()
    {
        std::cout << "Bitte Suchbegriff eingeben: ";
        
        std::string suchbegriff;
        std::getline(std::cin, suchbegriff);
     
        // Jetzt müssen wir die Daten noch in den vector laden...
        std::ifstream daten("c:\\presidents.txt", std::ios::in);
     
        while (daten.good())
        {
            std::string zeile;
            std::getline(daten, zeile);
            
            Daten.push_back(zeile);
        }
     
        daten.close();
     
     
        // Jetzt können wir jede Zeile durchsuchen, ob sie draufpasst
        // ---------------------------------------------------------------------
     
        // erstmal brauchen wir einen Zeiger auf den ersten Buchstaben des Suchbegriffes
        char* suchZeiger;
     
        // dann noch ein Zeiger auf den nächsten Buchstaben aus der zu durchsuchenden Zeile
        char* nächsterBuchstabe;
     
        std::cout << std::endl << std::endl << "Suchergebnisse:" << std::endl;
     
        //  Jetzt laufen wir alle eingelesenen Zeilen durch
        for (std::vector<std::string>::iterator i = Daten.begin(); i != Daten.end(); i++)
        {
            suchZeiger = &suchbegriff[0];
            nächsterBuchstabe = &(*i)[0];
     
            std::ostringstream ausgabe;
            bool offen = false;   // Speichert, ob gerade ein <Bereich> offen ist, oder alle geöffneten spitzen Klammern auch schon eine geschlossene haben
     
            // Für jedes Zeichen aus der zu durchsuchenden Zeile; eines der zwei breaks unten muss drankommen
            while(true)
            {
                // Wenn wir beim Suchbegriff ganz hinten angekommen sind, dann sind alle Zeichen in der richtigen Reihenfolge enthalten
                if (*suchZeiger == '\0')
                {
                    if (offen)
                        ausgabe << ">";   // Ggf. Noch die Klammer schließen
     
                    while (!*nächsterBuchstabe == '\0')   // und restliche Zeichen schreiben
                    {
                        ausgabe << *nächsterBuchstabe;
                        nächsterBuchstabe++;
                    }
     
                    std::cout << ausgabe.str().c_str() << std::endl;
                    break;
                }
     
                // Ist dagegen die Zeile zu Ende, gehen wir zur nächsten und fangen von vorne an
                if (*nächsterBuchstabe == '\0')
                    break;
     
                // Wenn eine Übereinstimmung gefunden wurde, setzen wir den suchZeiger auf das nächste Zeichen
                if (*suchZeiger == *nächsterBuchstabe)
                {
                    suchZeiger++;
                    
                    if (!offen)   // Bei Übereinstimmungen muss eine Klammer geöffnet werden, falls noch nicht geschehen
                    {
                        ausgabe << "<";
                        offen = true;
                    }
     
                    ausgabe << *nächsterBuchstabe;
                }
                else
                {
                    if (offen)   // Wenn grade keine Übereinstimmung da ist, dann die Klammer schließen, falls noch nicht geschehen
                    {
                        ausgabe << ">";
                        offen = false;
                    }
     
                    ausgabe << *nächsterBuchstabe;
                }
     
                // Der Zeiger in der aktuell zu durchsuchenden Zeile wird auf alle Fälle weitergesetzt
                nächsterBuchstabe++;
            }
        }
     
        std::cin.seekg(0,std::ios::end);
        std::cin.clear();
        std::cin.ignore();
        return 0;
    }

    Die Endlosschleife ist so hoffentlich erlaubt?
    Bei der Zeile hier frage ich mich, ob man die nicht einfacher schreiben kann?
    Code :
    1
    
    nächsterBuchstabe = &(*i)[0];

    Hoffentlich hab ichs nicht verschlimmbessert...
     

  4. #4
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.800
    Blog-Einträge
    5
    Hallo Markus,

    so gefällt es mir doch gleich viel besser Trotzdem noch ein paar Kleinigkeiten:

    Zitat Zitat von engelmarkus Beitrag anzeigen
    Code :
    1
    2
    3
    4
    5
    
    // Hier werden die Zeilen aus der Datei abgelegt
    std::vector<std::string> Daten;
    [...]
        // Jetzt müssen wir die Daten noch in den vector laden...
        std::ifstream daten("c:\\presidents.txt", std::ios::in);
    Zwei Variablennamen, die sich nur anhand der Groß-/Kleinschreibung unterscheiden, können sehr schnell für Verwirrung sorgen, daher am besten vermeiden!

    Zitat Zitat von engelmarkus Beitrag anzeigen
    Code :
    1
    2
    3
    4
    5
    
        // erstmal brauchen wir einen Zeiger auf den ersten Buchstaben des Suchbegriffes
        char* suchZeiger;
     
        // dann noch ein Zeiger auf den nächsten Buchstaben aus der zu durchsuchenden Zeile
        char* nächsterBuchstabe;
    Auch hier würde ich eher auf Iteratoren zurückgreifen (gibt es auch für Strings). Erstens ist nicht sichergestellt, dass char überhaupt der Basistyp eines std::string ist. Und zweitens kann es zu Problemen führen, wenn du mit der internen Repräsentation eines Datentyps arbeitest, ohne gesicherte Annahmen über selbige machen zu können (siehe weiter unten).

    Zitat Zitat von engelmarkus Beitrag anzeigen
    Code :
    1
    2
    
                // Wenn wir beim Suchbegriff ganz hinten angekommen sind, dann sind alle Zeichen in der richtigen Reihenfolge enthalten
                if (*suchZeiger == '\0')
    Hier kann es womöglich krachen, da nicht garantiert ist, dass std::strings intern als nullterminierte C-Strings gespeichert werden. Die meisten STLs handhaben es zwar so, aber es kann eben auch mal anders kommen.

    Zitat Zitat von engelmarkus Beitrag anzeigen
    Code :
    1
    
            std::cout << ausgabe.str().c_str() << std::endl;
    Hier reicht auch ausgabe.str().

    Zitat Zitat von engelmarkus Beitrag anzeigen
    Bei der Zeile hier frage ich mich, ob man die nicht einfacher schreiben kann?
    Code :
    1
    
    nächsterBuchstabe = &(*i)[0];
    Code :
    1
    
    nächsterBuchstabe = i->c_str();
    Allerdings müsste dann nächsterBuchstabe als const char* deklariert werden. Da die Verwendung von char* in Verbindung mit std::string aber sowieso problematisch ist (s.o.), erübrigt sich die Frage

    Grüße,
    Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  5. #5
    engelmarkus engelmarkus ist offline Mitglied Brokat
    Registriert seit
    Sep 2007
    Beiträge
    473
    Also noch eine Version :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <vector>
     
    // Hier werden die Zeilen aus der Datei abgelegt
    std::vector<std::string> Daten;
     
    int main()
    {
        std::cout << "Bitte Suchbegriff eingeben: ";
        
        std::string suchbegriff;
        std::getline(std::cin, suchbegriff);
     
        // Jetzt müssen wir die Daten noch in den vector laden...
        std::ifstream datei("c:\\presidents.txt", std::ios::in);
     
        while (datei.good())
        {
            std::string zeile;
            std::getline(datei, zeile);
            
            Daten.push_back(zeile);
        }
     
        datei.close();
     
     
        // Jetzt können wir jede Zeile durchsuchen, ob sie draufpasst
        // ---------------------------------------------------------------------
     
        // erstmal brauchen wir einen Zeiger auf den ersten Buchstaben des Suchbegriffes
        std::string::iterator suchZeiger;
     
        // dann noch ein Zeiger auf den nächsten Buchstaben aus der zu durchsuchenden Zeile
        std::string::iterator nächsterBuchstabe;
     
        std::cout << std::endl << std::endl << "Suchergebnisse:" << std::endl;
     
        //  Jetzt laufen wir alle eingelesenen Zeilen durch
        for (std::vector<std::string>::iterator i = Daten.begin(); i != Daten.end(); i++)
        {
            suchZeiger = suchbegriff.begin();
            nächsterBuchstabe = (*i).begin();
     
            std::ostringstream ausgabe;
            bool offen = false;   // Speichert, ob gerade ein <Bereich> offen ist, oder alle geöffneten spitzen Klammern auch schon eine geschlossene haben
     
            // Für jedes Zeichen aus der zu durchsuchenden Zeile; eines der zwei breaks unten muss drankommen
            while(true)
            {
                // Wenn wir beim Suchbegriff ganz hinten angekommen sind, dann sind alle Zeichen in der richtigen Reihenfolge enthalten
                if (suchZeiger == suchbegriff.end())
                {
                    if (offen)
                        ausgabe << ">";   // Ggf. Noch die Klammer schließen
     
                    while (nächsterBuchstabe != (*i).end())   // und restliche Zeichen schreiben
                    {
                        ausgabe << *nächsterBuchstabe;
                        nächsterBuchstabe++;
                    }
     
                    std::cout << ausgabe.str() << std::endl;
                    break;
                }
     
                // Ist dagegen die Zeile zu Ende, gehen wir zur nächsten und fangen von vorne an
                if (nächsterBuchstabe == (*i).end())
                    break;
     
                // Wenn eine Übereinstimmung gefunden wurde, setzen wir den suchZeiger auf das nächste Zeichen
                if (*suchZeiger == *nächsterBuchstabe)
                {
                    suchZeiger++;
                    
                    if (!offen)   // Bei Übereinstimmungen muss eine Klammer geöffnet werden, falls noch nicht geschehen
                    {
                        ausgabe << "<";
                        offen = true;
                    }
     
                    ausgabe << *nächsterBuchstabe;
                }
                else
                {
                    if (offen)   // Wenn grade keine Übereinstimmung da ist, dann die Klammer schließen, falls noch nicht geschehen
                    {
                        ausgabe << ">";
                        offen = false;
                    }
     
                    ausgabe << *nächsterBuchstabe;
                }
     
                // Der Zeiger in der aktuell zu durchsuchenden Zeile wird auf alle Fälle weitergesetzt
                nächsterBuchstabe++;
            }
        }
     
        std::cin.seekg(0,std::ios::end);
        std::cin.clear();
        std::cin.ignore();
        return 0;
    }
     

Thema nicht erledigt

Ähnliche Themen

  1. [QUIZ#2] engelmarkus (VB.Net)
    Von engelmarkus im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 28.09.08, 17:57
  2. [QUIZ#1] engelmarkus (VB.Net)
    Von engelmarkus im Forum Archiv
    Antworten: 0
    Letzter Beitrag: 20.09.08, 17:09
  3. Quiz?
    Von MeisterLampion im Forum Office-Anwendungen
    Antworten: 12
    Letzter Beitrag: 03.11.06, 15:48
  4. Quiz
    Von alkaline im Forum PHP
    Antworten: 0
    Letzter Beitrag: 27.09.04, 10:16
  5. php Quiz
    Von Sim im Forum PHP
    Antworten: 0
    Letzter Beitrag: 09.05.04, 12:43