datenbank als std::list



  • naja bin mir nicht ganz sicher wie mir das jetzt helfen soll.

    ich kenne verkettete listen aus anderen sprachen - auch arrays oder vektoren sind mir bekannt.
    das ich das ganze mit iteratoren durchgehen kann ist mir auch klar.

    Ich hab mir einfach gedacht list ist wohl das geeignetste - zumindes von den objekten die ich bisher gesehen hab.
    die frage war einfach ob ich bzw. wie ich mit einer eigenen struktur die ich in eine liste speichere die sort methode verwenden kann - und welche struktur ich dann am bessten nehme um das in eine liste zu speichern.

    also kann ich wenn ich ein struct der form:
    string titel
    string adresse
    string name
    habe der sort methode im list objekt sagen kann er soll adresse zum sortieren verwenden.

    oder hab ich da was falsch verstanden?

    lg
    Verucca



  • Nach was sortiert werden soll, kannst du mit einem Prädikat BinPred p bestimmen:
    http://www.cppreference.com/cpplist/sort.html

    Deshalb sollte man sich mit der Standardlib beschäftigen, da dort ganz bestimmte Konzepte angewendet werden. Diese Konzepte gelten auch für andere Algorithmen. Auch muß man sich mit Operator-Überladung auskennen (ist einfach, muß man aber einmal verstehen) da dies für die Sortier-Algos in C++ benötigt wird.

    Wenn du einen vector benutzt, kannst du diesen natürlich auch sortieren lassen. Da gibts Sortieralgorithmen in der Std-Lib. Du könntest auch eine map benutzen, die Schlüssel-Wert-Paare speichert.

    Die drei Links oben sind halt Tutorials, die einem alles soweit erklären. Deshalb helfen sie dir weiter!



  • std::list halte ich für sowas für ungeeignet. Immerhin kann man darin überhaupt nicht rumspringen, das heißt die Sortierung nützt garnix. Man muß sowieso immer von vorne bis zum gesuchten Element hinlaufen. Nahezu jeder andere Container dürfte besser geeignet sein.



  • Hier mal ein Beispiel, für einen Denkanstoss:

    bool adress_pred(const Person &p1, const Person &p2)
    {
        return p1.get_adresse() < p2.get_adresse();
    }
    
    bool name_pred(const Person &p1, const Person &p2)
    {
        return p1.get_name() < p2.get_name();
    }
    
    std::list<Person> adressen;
    //...
    
    adressen.sort(adress_pred);   // nach Adresse sortieren
    adressen.sort(name_pred);     // nach Name sortieren
    

    Standardlib lernen würde ich trotzdem, sonst kann man C++ nicht ausreizen und nicht vernünftig arbeiten.



  • Jester schrieb:

    std::list halte ich für sowas für ungeeignet. Immerhin kann man darin überhaupt nicht rumspringen, das heißt die Sortierung nützt garnix. Man muß sowieso immer von vorne bis zum gesuchten Element hinlaufen. Nahezu jeder andere Container dürfte besser geeignet sein.

    Naja, Verruca hat in vector keine sort-Methode gesehen, also geht er/sie davon aus, das man ihn nicht einfach sortieren kann. Hat halt keinen Schimmer von der Standardlib und wie man diese mit einer Zeile Code sortieren kann.



  • hi
    Danke für die vielen Antworten.
    Und ja ich hab keine Ahnung von der Std.
    Auch hab ich keinen dunst von c++ - ich muss mich allerdings jetzt schnell einarbeiten.
    Ich hab vorher Java, Delphi und ein paar andere sachen gemacht, deshalb steh ich etwas wie die Kuh vorm Dorf .....

    ad. List

    std::list halte ich für sowas für ungeeignet.

    deshalb hab ich ja mal nach einer classe gefragt die dafür geeignet wäre .....
    herumspringen muss ich eigentlich eh nicht - ja suchen sollte man schon können, aber die sortierung ist vor allem für die ausgabe wichtig und ich erwarte keine großen datenstrukturen.

    Jetzt zu dem codebeispiel - das einer offenbarung gleicht 🙂

    bool adress_pred(const Person &p1, const Person &p2)
    {
    return p1.get_adresse() < p2.get_adresse();
    }

    bool name_pred(const Person &p1, const Person &p2)
    {
    return p1.get_name() < p2.get_name();
    }

    std::list<Person> adressen;
    //...

    adressen.sort(adress_pred); // nach Adresse sortieren
    adressen.sort(name_pred); // nach Name sortieren

    nach diesem vorschlag soll ich eine klasse schreiben die seter und geter beinhaltet.
    ( bzw. scheint es egal zu sein im falle einse structs geb ich hald die referenz auf die variablen and ).
    und dann übergeb ich dem sort die methode wie sortiert werden soll - das ist genial - da kommt wohl eine der stärken von c++ mit dem umgang mit generics heraus.

    jedenfalls muss ich mir jetzt noch ein bisschen methoden für stringzerlegung anschauen und schon kann ich loslegen.

    ganz durchblicken tu ich noch nicht was ich jetzt wirklich verwenden soll - aber ich denke mal eine liste ist für den anfang ganz ok.
    ein vektor hat ja scheinbar den nachteil, dass ich wieder schwerer elemente einfügen kann.
    und den index brauch ich bei meinem beispiel eh nicht, weil ich ja sowieso nach dem richtigen element suchen muss und da werde ich wohl eh die ganze liste durchgehen müssen.
    um schnell zu suchen müsste ich eh einen binärbaum nehmen und wie gesagt erwarte ich nicht sehr große datenmengen.

    Danke nochmals - da ich keinen dunst von c++ hab werde ich wohl noch viele viele fragen haben 🙂

    lg
    Verucca



  • Crashkurs für Container und Algorithmen in C++:
    http://www.kharchi.de/cppratgeber2.htm
    http://www.kharchi.de/iteratoren.html



  • Datenbanken und C++?
    -> SQLite (is C, gibt aber C++ Wrapper)
    -> Boost.MultiIndex
    -> std::map/set, xxx::hash_map/hash_set

    In absteigender Reihenfolge der Mächtigkeit 🙂

    p.S.: SQLite kann auch "in memory" Datenbanken und ist recht flott. Sicher langsamer als Boost.MultiIndex oder ein einfacher Standardcontainer, aber immer noch recht schnell für ne Datenbank, und du kannst SQL verwenden zum joinen, filtern und sortieren.



  • Hallo nochmal
    Ich bin gerade am herumprobieren mit der sort funktion.
    2 fragen hab ich dazu zum besseren verständnis:
    1.
    funktioniert wunderbar nur sortiert der natürlich case sensitive.
    wie sortiere ich nicht case sensitive?

    return strupr(p1.getTitle()) < strupr(p2.getTitle());
    

    funktioniert nicht in dem zusammenhang oder ich mach etwas falsch :).

    2. mit den zu übergebenden typen hab ich noch probleme
    so hat es nämlich nicht funktioniert:

    bool interpret_pred(const entry &p1, const entry &p2)
    {
        return p1.getInterpret() < p2.getInterpret();
    }
    

    wenn ich das ohne const anschreibe funktioniert es.
    wie soll ich das const in dem zusammenhang verstehen?

    Danke
    Verucca



  • hustbaer schrieb:

    Datenbanken und C++?
    -> SQLite (is C, gibt aber C++ Wrapper)
    -> Boost.MultiIndex
    -> std::map/set, xxx::hash_map/hash_set

    In absteigender Reihenfolge der Mächtigkeit 🙂

    p.S.: SQLite kann auch "in memory" Datenbanken und ist recht flott. Sicher langsamer als Boost.MultiIndex oder ein einfacher Standardcontainer, aber immer noch recht schnell für ne Datenbank, und du kannst SQL verwenden zum joinen, filtern und sortieren.

    es gibt auch noch die DTL. Wobei ich nicht weiß, wie gut die ist 🙂



  • @1: Woher stammt denn die strupr()-Funktion (und wie ist sie definiert)? Und was für Fehler gibt es mit diesem Konstrukt?

    @2: Setz mal die Methode getInterpret() (und die übrigen Getter-Methoden) deiner Person-Klasse const:

    class Person
    {
    ...
    public:
      string getInterpret() /*hier:*/const
      { return m_interpret; }
    ...
    };
    


  • Wenn du nicht casesensitive vergleichen willst, mach doch vorher die beiden strings komplett upper- oder lowercase. (temporär versteht sich)

    const heißt, das die entries nicht verändert werden. Anscheinend sind deine getter nicht const, so das der compiler berechtigterweise dich davor abhält, eine verändernde Funktion aufzurufen.

    Entweder du machst die Getter const (weil getter meistens nichts ändern, sondern nur was zurück geben), oder du machst die parameter nicht-const (was ich aber unlogisch finde).



  • Tip: http://www.boost.org/doc/html/string_algo/usage.html#id2742674

    oder mit der Stdlib:

    std::string s ("HaLLeLuJa");
    
    std::transform (s.begin(),s.end(), s.begin(), tolower);
    


  • Artchi schrieb:

    std::transform (s.begin(),s.end(), s.begin(), tolower);
    

    Wird u.U. schiefgehen, wenn die Implementierung tolower nicht als Funktion sondern nur als Makro anbietet (keine Ahnung ob das durch den Standard erlaubt ist wenn in der Definition von "the tolower function" die Rede ist, aber bei bestimmten G++-Versionen ist es der Fall). Dann einfach eine eigene (inline-)Funktion hernehmen, die tolower aufruft 😉



  • Hallo,

    Da gibts doch noch was von Hume
    http://fara.cs.uni-potsdam.de/~kaufmann/stricmp.h



  • Wenn du die Liste immer sortiert haben willst bietet sich vielleicht ein std::set oder std::multiset an. Kannst dir die beiden ja mal ansehen.



  • Hi
    Ich arbeite mich langsam so durch die std

    ich wollte das als keymap implementieren ( zumindestens für meine entry klasse um die dann in eine list einzufügen )

    allerdings bin ich drauf gekommen, dass keymap das immer sortiert.
    das ist ein problem, weil ich eine methode toString einbauen wollte, die mir gleich die aus allen values der keymap einen string baut.
    nur sind die natürlich alphabetisch sortiert und das ist ein problem für mich.
    gibt es eine möglichkeit das zu unterbinden bzw. die reihenfolge der einträge so zu bekommen wie sie angelegt wurden - oder kann ich die keymap in dem fall vergessen?.

    lg
    Verucca



  • Hi,

    also wenn Du keine Sortierung nach keyvalue haben möchtest, kannst Du einfach einen vector nehmen - allerdings sorgt der auch nicht für "uniqueness":

    std::vector<pair<keyval, data> > v;
    

    Wenn ich mich nicht täusche, gibt's in der STL keinen Container, der "uniqueness" sichert trotzdem nicht sortiert...
    Zur Not (wenn es nicht beim Eintragen schon erkannt werden soll) kannst Du das mittels unique() hinterher korrigieren.

    Oder Du nutzt eine

    std::map<keyval, pair<entryNo, data> > m;
    

    oder gleich

    struct keyValAndEntryNo {
       keyval k;
       entryNo e;
    };
    
    std::multimap<keyValAndEntryNo, data> > m;
    

    (mit einem geeigneten Komparator (der nur k vergleicht))

    ... und sortierst bei der Nutzung. (ungeschickterweise ist dabei entryNo nicht mehr eindeutig)

    Gruß,

    Simon2.



  • hey c++ ist echt cool 🙂

    aber wie iterier ich dann über das ding?

    vector<string,string>::iterator iter;
    for( iter = keymap.begin(); iter != keymap.end(); ++iter ) 
    {
        cout << "Key: '" << iter->first << "', Value: " << iter->second << endl; 
    }
    

    so geht es vermutlich nicht - aber wie deffinier ich den iterator richtig?

    lg
    verucca

    edit:
    und scheinbar hab ich dann nicht so eine praktische find methode - die müsste ich mir dann wohl selbst schreiben.
    das war ja das schöne an der keymap "keymap.find(key)" usw

    und ich seh schon so wird das gemacht:

    vector<pair<string, string> >::iterator iter;
      	for( iter = keymap.begin(); iter != keymap.end(); ++iter ) 
      	{
        cout << "Key: '" << iter->first << "', Value: " << iter->second << endl; 
        }
    

    allerdings werd ich mir wohl alle funktionen einer keymap selbst schreiben müssen.
    also find usw....
    naja egal - es ist brauchbar..
    lg
    Verucca



  • Naja, es gibt doch auch ein find() in der STL:
    http://www.cppreference.com/cppalgorithm/index.html

    😃

    Gruß,

    Simon2.


Anmelden zum Antworten