datenbank als std::list
-
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 sortierenStandardlib 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 sortierennach 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_setIn 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_setIn 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 stdich 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
veruccaedit:
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)" uswund 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.
-
Nach was willst du denn suchen? Eine map hat Schlüssel, weil man nach ebend diesen eigentlich suchen will. Und find von map ist dann genau richtig.
-
naja das ganze dient ja haupsächlich dazu cpp zu lernen :).
aber ich schreib immer noch an dieser minni datenbank
funtioniert ja schon alles ganz gut, nur möchte ich das jetzt etwas generischer angehen - etwas hald ....ich erstelle also eine classe entry die im prinzip als keymap funktioniert.
man kann also einen key erstellen und values speichern
Beispiel:
adress foo
name bar
usw...
als methoden;
string get(string key)
set(string key, string value)
insert (string key) // adds a new keyvalue to database.
delete (string key) // removes a key.
string toString() // liefert einen string über den ganzen datensatz zurück.der construktor von dem datenbank objekt wird jetzt mit der entry klasse gefüttert.
die datenbank kann jetzt die key felder auslesen und weiß genau was verwaltet werden soll.
in eine std::list wird dann classe entry als datensatz eingefügt.jetzt werden noch suchmethoden und sortieren bzw. suchen mit sortierter ausgabe implementiert und schon ist das fertig.
dann noch methoden database.loadfromfile, database.savetofile und es ist halbwegs komplett.für die entry klasse hab ich mir zuerst eine keymap gedacht - sozusagen ein wrapper für die map mit ein paar mehr methoden ( toString zum beispiel )
bis ich dauf gekommen bin, das das sortiert wird war die idee eh ganz nett - aber schließlich muss der datensatz schon die reihenfolge beibehalten ... - sonst gibts beim speichern und laden vom file probleme - da würden dann irgendwann falsche werte rein kommen usw zumindestens wenn man sich hier eine sinnvolle reihenfolge vorstellt.vorname nachname adress plz ......
ich beweg mich eh schön langsam durch die std - man braucht hald ein projekt um eine sprache zu lernen

lg
Veruccaedit:
aber gleich eine frage dazu.
wie soll ich bei einem pair den zugreifen auf das element?
std::find liefert einen iterator zurück ... ok.vector<pair<string, string> >::iterator iter; iter = find( keymap.begin()->first, keymap.end()->first, "type" );wie finde ich da die elemente - ist eine interessante methode - ich hätte ja klassisch ein 2 dimensionales array genommen ...
-
Warum benutzt du nicht die find von map? Aber was du mit "elemente" meinst, weiß ich nicht.