Substrings innerhalb eines Strings sortieren



  • @Bibigon sagte in Substrings innerhalb eines Strings sortieren:

    Löse ich die Aufgabe am besten mit einem Container oder C-Array? Falls Container, welcher Art: vector, map, multimap usw.?
    Und das wichtigste: wie am effektivsten (Algorithmus)?

    Lass die Finger weg von C-Arrays, nimm die STL (std::vector, std::map, ...)! Das nimmt dir jede Menge Arbeit ab!

    Anfangs würde ich die Effektivität auch mal nach hinten schieben. Schaue erst einmal dass du das Programm zum laufen bringst. Später kannst du immer noch einen größeren Test machen und ggf. optmieren.

    BTW:
    Könntest du auch mal ein verständlicheres Beispiel geben, welche dein Problem klarer beschreibt? Evt. so: "Gruppe: Songtitel, Gruppe: Erscheinungsdatum,..." ?



  • @SeppJ
    Danke dir! Genau an dieser Art von Hilfe habe ich gedacht.
    Die Aufgabe ist nicht aus der Informatikunterricht.
    Brauche jetzt nur ein Paar Stunden freier Zeit zum Code schreiben.
    Auf jeden Fall, vielen Dank voresrt!



  • @Quiche-Lorraine

    Danke für die Tipps!
    So werde ich auch weiter vorgehen.

    Zum Beispiel:
    Man hat z. B. als Schmuck-CADler im Laufe des Jahres einige CAD-Modelle im Archiv.

    Schmuckart: Ring, Armband, Collier, Ohrstecker, Ohrhänger, Anhänger usw
    Legierung: 750 Gelbgold, 750 Weissgold, 585... , Plating, Silber usw
    Steinart: Diamant, Smaragd, Rubin, ...
    Steinanzahl: 1, 2, 3, ..
    Perlenart: FWP, SCP, Akoya, ...
    Perlenanzahl: 1, 2, ...
    Ringweite: 48, 49, ...
    Länge: 40, 42, 45...
    Zusätzliches: Handgravur, Lasergravur, Guilloche, ...
    .
    .
    .
    Ich überlege wie ich die Modelle am effektivsten archiviere und die im Archiv dann am schnellsten finde.



  • @Bibigon sagte in Substrings innerhalb eines Strings sortieren:

    Ich überlege wie ich die Modelle am effektivsten archiviere und die im Archiv dann am schnellsten finde.

    Ah ok!

    Mal eine weitere Frage: Wären dann auch Abfragen der Form "Zeige mir mal bitte jedes Schmuckstück aus Silber" wünschenswert?



  • @Quiche-Lorraine
    Die Abfragen sind vorerst zweitrangig. Mir geht es in der erste Linie gerade um Archivstardardisierung.



  • @Bibigon
    Naja, ich frage mich halt bloß ob du eine Datenbank ala SQL benötigst.

    Ist das ein Hobby-Projekt für dich oder musst du wirklich Daten archivieren?


  • Gesperrt

    Dieser Beitrag wurde gelöscht!

  • Gesperrt

    Dieser Beitrag wurde gelöscht!


  • @SeppJ

    Habe deinem Tipp gefolgt:

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <vector>
    #include <map>
    #include <string>
    #include <algorithm>
    
    // Liste der bekannten Substrings
    const std::map<int, std::vector<std::string>> mTeilstrings = {
        {1, {"[8A]", "[UKE]"}},
        {2, {"[Dings da]", "[DingsBums]"}},
        {3, {"[GF]", "[MOD]", "[MOD3]", "[MOD6]"}},
        {4, {"[Weiss]", "[Rot]", "[Orange-Blau]"}}
    };
    
    int main() {
        std::ifstream ifsDatei("Zu_Sortieren.txt");
        std::string strZeile, strTeilstring;
        bool Gefunden=true; // für Fehler "unbekannter Substring"
        bool GruppenDuplikat; // für "Gruppenduplikat"-Fehler
    
        if (ifsDatei.is_open()) { // Datei öffnen
            while (std::getline(ifsDatei, strZeile)) { // Datei zeilenweiser einlesen
                std::stringstream strstrmZeile(strZeile); // Stringstream zum Aufteilen
                std::map<int, std::string> mSortierteString; // Container für sortierten String
                GruppenDuplikat = false;
                std::cout << strZeile << "  ->  ";
                while(std::getline(strstrmZeile, strTeilstring, ']') && (Gefunden || !GruppenDuplikat)) { // Aufteilung in Substrings
                    strTeilstring += ']';
                    Gefunden = false;
                    for (auto const& [keyPosition, vTeilstrings] : mTeilstrings) { // Suche nach dem Substring in der Liste
                        auto it = std::find(vTeilstrings.begin(), vTeilstrings.end(), strTeilstring); // Suche nach dem Substring in der Gruppe
                        if (it != vTeilstrings.end()) {
                            Gefunden = true;
                            if (!mSortierteString.count(keyPosition)) { // falls kein Substring aus der gleichen Gruppe bereits im Container
                                mSortierteString.insert({keyPosition, strTeilstring}); // füge dem Container zu
                            }
                            else {
                                GruppenDuplikat=true;
                                std::cout << "Fehler: Gruppenmitglied bereits vorhanden! " << strTeilstring << " & " << mSortierteString[keyPosition] << std::endl;
                                break;
                            }
                        }
                    }
                    if ( !Gefunden ) { // falls ein unbekannter Substring
                        std::cout << "Fehler: unbekannter Substring " << strTeilstring << "!";
                    }
                }
                if (Gefunden && ! GruppenDuplikat ) // Ausgabe fehlerfreien sortierten String
                    for (const auto& [schluessel, wert] : mSortierteString) {
                        std::cout << wert;
                    }
                std::cout << std::endl;
            }
            ifsDatei.close(); // Datei schließen
        } else {
            std::cerr << "Datei konnte nicht geöffnet werden." << std::endl;
            return 1;
        }
        return 0;
    }
    

    Zu_Sortieren.txt

    [8A][Dings da][Orange-Blau]
    [MOD][Weiss][UKE]
    [GF][MOD3][Dings da]
    [MOD][Black][UKE]
    [GF][MOD3][Dings da][GF][MOD3][Dings da]

    Funktioniert noch nicht zufriedenstellend.
    Was ich zum Verrecken nicht hinkriege, ist die Umschreibung der for-Schleife:

    for (auto const& [keyPosition, vTeilstrings] : mTeilstrings) { // Suche nach dem Substring in der Liste
    

    in eine while-Schleife, damit ich die Schleife nach dem ersten Fehler unterbrechen kann.

    while(Iterator!=mTeilstring.end() && (Gefunden || !GruppenDuplikat)) {
    ...
    }
    

    Ich verstehe es einfach nicht (auch Googlen hiflt nicht🤦🏻♂ ), wie kriege ich den keyPosition-Wert heraus.

    Die etwas holprige Ausgabe sieht zur Zeit folgendermassen aus:

    [8A][Dings da][Orange-Blau] -> [8A][Dings da][Orange-Blau]
    [MOD][Weiss][UKE] -> [UKE][MOD][Weiss]
    [GF][MOD3][Dings da] -> Fehler: Gruppenmitglied bereits vorhanden! [MOD3] & [GF]

    [MOD][Black][UKE] -> Fehler: unbekannter Substring [Black] [UKE][MOD]
    [GF][MOD3][Dings da][GF][MOD3][Dings da] -> Fehler: Gruppenmitglied bereits vorhanden! [MOD3] & [GF]
    Fehler: Gruppenmitglied bereits vorhanden! [GF] & [GF]
    Fehler: Gruppenmitglied bereits vorhanden! [MOD3] & [GF]
    Fehler: Gruppenmitglied bereits vorhanden! [Dings da] & [Dings da]

    Vielen Dank im Voraus!



  • @Bibigon
    Schau mal Sepp wollte ein vector<pair<string, int>>. Was spricht also gegen mTeilstrings ala {[8A], 1}, {[UKE], 1}, {[Dings da], 2}... Dein Integer Wert entspricht hier ja einer Kategorien ID.

    Dann liest du deine Eingabe (z.B. "[8A][Dings da][Orange-Blau]") ein und zerlegt diese in einzelne Tokens ("[8A]", "[Dings da]", "[Orange-Blau]")

    Dann suchst du zu jedem Token einen Eintrag in mTeilstrings. Gebe eine Fehlemeldung aus, wenn du keinen Eintrag gefunden hast. Ansonsten füge das Ergebnis einer Result = vector<string, int> Variable hinzu.

    Wenn du damit fertig bist, sortiere Result nach der Kategorien-ID (int Wert).

    Danach überprüfst du das Ergebnis. Per Definition darf eine Kategorien-ID nicht doppelt vorkommen. Und durch die Sortierung ist es garantiert dass im Falle eines Falles diese aufeinanderfolgt.

    Und danach gibst du das Ergebnis aus.


  • Mod

    Genau. Du versuchst da einen Schritt abzukürzen, den ich bewusst nicht abgekürzt habe, da du versuchst direkt beim Lesen an die richtige Stelle des Ergebnisses zu schreiben, anstatt erst einmal zu sammeln. Was löblich ist — wahrscheinlich sogar machbar wenn man ein bisschen tüftelt —, aber macht es halt schwieriger. Ich würde mich erst einmal genau Schritt für Schritt an meinen Vorschlag halten. Da kann man auch gut jeden Teilschritt nacheinander programmieren und jeweils das Zwischenergebnis angucken, ob es noch passt. Derzeit hast du 7 Ebenen Einrückung. Verwirrend. Stattdessen lieber so programmieren, dass man 7 Mal 1-2 Ebenen Einrückung hat, auch wenn's ein paar Zeilen länger wird.


Anmelden zum Antworten