grosse Datenmengen - wie in der App halten?
-
Moin ihr Frühaufsteher

Ja ne, is klar

Sortieren nach: 3 Spalten, 1 x long, 2 x CString, auf / absteigend, je nach vorheriger Sortierung.
Das Problem ist wie schon gesagt das mitziehen der structs im vectot.
std::sort( bzw. vector::sort ) hatte ich schon.habe testweise mal die Daten( hier CString ) in einen eigenen std::vector<CString> gewuchtet, den dann mit seiner eigenen sort sortiert. Bis hierher ohne spürbare Zeitverluste. Dann müssen die Daten aber wieder 'zusammengeführt' werden, sprich in aktueller Reihenfolge zurück in vector. Das bedeutet Kaffeepause. Aber nicht nur trinken, sonder auch noch Zeit Kaffee anzubauen und zu ernten

ausserdem habe ich keine Lösung bei std::sort für die Behandlung von Umlauten gefunden. Schnell ist der schon.
Code Marsch!
int iChk1, iChk2; int wg = lstVect.size(); std::vector<LCSTRUCT>::iterator tmxIter; std::vector<LCSTRUCT>::iterator tmpIter; for( tmxIter = lstVect.begin(); tmxIter != lstVect.end(); tmxIter++ ) { lstStruct = *tmxIter; tmpIter = tmxIter; tmpIter++; if( col == 0 ) { iChk1 = lstStruct.vNmbr; if( tmpIter != lstVect.end() ) { srtStruct = *tmpIter; iChk2 = srtStruct.vNmbr; } else continue; if( up ) { while( iChk1 > iChk2 ) { if( tmpIter != lstVect.end() ) std::iter_swap( tmpIter, tmxIter ); tmpIter++; if( tmpIter != lstVect.end() ) { srtStruct = *tmpIter; iChk2 = srtStruct.vNmbr; } else break; } } else { while( iChk1 < iChk2 ) { if( tmpIter != lstVect.end() ) std::iter_swap( tmxIter, tmpIter ); tmpIter++; if( tmpIter != lstVect.end() ) { srtStruct = *tmpIter; iChk2 = srtStruct.vNmbr; } else break; } } } }Das ist Spalte 1( Zahl ). Nur mal zu Bsp.
grüssle

-
Smitty schrieb:
Das Problem ist wie schon gesagt das mitziehen der structs im vectot.
std::sort( bzw. vector::sort ) hatte ich schon.Ich wußte gar nicht, daß vector<> eine sort-Methode mitliefert

ausserdem habe ich keine Lösung bei std::sort für die Behandlung von Umlauten gefunden. Schnell ist der schon.
Du mußt dir für jede deiner Sortierfolgen eine eine eigene Vergleichsfunktion schreiben, die auf die jeweiligen Eigenheiten eingeht - der normale String-Vergleich arbeitet mit den ASCII-Werten, dadurch landen Umlaute üblicherweise am Ende der Liste.
(wenn du die Umlaute im Alphabet einschieben willst, mußt du eine eigene Vergleichsfunktion schreiben - oder ein deutsches Locale zum Vergleichen verwenden)
PS: Wo hast du denn diesen Sortieralgorithmus her?
-
CStoll schrieb:
Smitty schrieb:
Das Problem ist wie schon gesagt das mitziehen der structs im vectot.
std::sort( bzw. vector::sort ) hatte ich schon.Ich wußte gar nicht, daß vector<> eine sort-Methode mitliefert

Der vector::sort ist nicht von mir. Guckst du weiter oben
( war wohl std::sort gemeint
)CStoll schrieb:
Du mußt dir für jede deiner Sortierfolgen eine eine eigene Vergleichsfunktion schreiben, die auf die jeweiligen Eigenheiten eingeht - der normale String-Vergleich arbeitet mit den ASCII-Werten, dadurch landen Umlaute üblicherweise am Ende der Liste.
(wenn du die Umlaute im Alphabet einschieben willst, mußt du eine eigene Vergleichsfunktion schreiben - oder ein deutsches Locale zum Vergleichen verwenden)
Auch klar. habe ich auch gemacht. Funzt auch. Nur nicht mit dem:
std::sort( hVect.begin(), hVect.end(), std::greater<CString>() );CStoll schrieb:
PS: Wo hast du denn diesen Sortieralgorithmus her?
Sag ich nicht :p
Ne, hab ich mir mal quick&dirty so zusammengekloppt. Tut seinen Dienst, ist aber wohl nicht der weisheit letzter Schluss
grüssle

-
mach doch ne eigene sortier funktion:
// struktur definieren und vector fuellen, das hast du ja schon struct DATA { CString strA; CString strB; int i = 0; }; vector<DATA> bla; /* - fill - */ // merkt sich wie rum du sortieren moechtest bool bDirectionA = false; // sortiere nach strA bool SortByA(const DATA &l, const DATA &r) { if(bDirectionA) return l.strA < r.strA; else return l.strA > r.strA; } // richtung umkehrem und sortieren bDirectionA = (bDirectionA) ? false : true; std::sort(bla.begin(), bla.end(), SortByA);
-
Smitty schrieb:
CStoll schrieb:
Du mußt dir für jede deiner Sortierfolgen eine eine eigene Vergleichsfunktion schreiben, die auf die jeweiligen Eigenheiten eingeht - der normale String-Vergleich arbeitet mit den ASCII-Werten, dadurch landen Umlaute üblicherweise am Ende der Liste.
(wenn du die Umlaute im Alphabet einschieben willst, mußt du eine eigene Vergleichsfunktion schreiben - oder ein deutsches Locale zum Vergleichen verwenden)
Auch klar. habe ich auch gemacht. Funzt auch. Nur nicht mit dem:
std::sort( hVect.begin(), hVect.end(), std::greater<CString>() );Ja, eine struct als CString zu vergleichen macht sich nicht so gut - da mußt du dir eine eigene Funktion schreiben, die das gewünschte Element herausnimmt und vergleicht:
bool compare_string1(const data& l,const data& r) { return l.s1<r.s1; } //analog compare_string2() und compare_int() //Und als besonderes Schmankerl für die umgekehrte Sortierung: struct inverse : public binary_function<bool,data,data> { typedef bool (*comp_fn)(const data&,const data&); inverse(comp_fn func) : m_func(func) {} bool operator()(const data& l,const data& r) { return m_func(r,l); } private: comp_fn m_func; }; // Verwendung: ... sort(hVect.begin(),hVect.end(),compare_string1);//aufsteigend nach erstem String sort(hVect.begin(),hVect.end(),inverse(compare_int));//absteigend nach ZahlCStoll schrieb:
PS: Wo hast du denn diesen Sortieralgorithmus her?
Sag ich nicht :p
Ne, hab ich mir mal quick&dirty so zusammengekloppt. Tut seinen Dienst, ist aber wohl nicht der weisheit letzter Schluss
bestimmt nicht - und statt etwas eigenes zu programmieren nach dem Motto "tut seinen Dienst", solltest du lieber auf die Arbeit von Experten vertrauen - da gibt es genug Verfahren, die meilenweit besser sein dürften* (such mal nach "QuickSort", "MergeSort" oder "HeapSort").
* nein, ich hab' dein Verfahren jetzt nicht im Detail analysiert
-
Mach dir doch ne kleine Datenbank bevor du dir über den ganzen Kram den Kopf zerbrichst. Access über DAO, ist schnell implementiert und die haben den ganzen Sortier-Kram schon erforscht
An sonsten würde ich einen Algorithmus vorschlagen, der die Elemente schon beim Einfügen vorsortiert (Heap-Sort? )
-
Cpp_Junky schrieb:
An sonsten würde ich einen Algorithmus vorschlagen, der die Elemente schon beim Einfügen vorsortiert (Heap-Sort? )
Ja, das hätte ich auch vorgeschlagen (allerdings eher mit einem vorsortierten Container - set<>). Das Problem dabei ist aber, daß der OP das Sortierkriterium zwischendurch ändern will - und eine nach Vornamen sortierte Liste bringt keine Vorteile, wenn du die Daten nach Alter auflisten willst.
-
CStoll schrieb:
Ich wußte gar nicht, daß vector<> eine sort-Methode mitliefert

Sorry. Meinte natürlich std::sort, habe es in der Eile mit list<>::sort
-
CStoll schrieb:
Ja, eine struct als CString zu vergleichen macht sich nicht so gut - da mußt du dir eine eigene Funktion schreiben, die das gewünschte Element herausnimmt und vergleicht:
bool compare_string1(const data& l,const data& r) { return l.s1<r.s1; } //analog compare_string2() und compare_int() //Und als besonderes Schmankerl für die umgekehrte Sortierung: struct inverse : public binary_function<bool,data,data> { typedef bool (*comp_fn)(const data&,const data&); inverse(comp_fn func) : m_func(func) {} bool operator()(const data& l,const data& r) { return m_func(r,l); } private: comp_fn m_func; }; // Verwendung: ... sort(hVect.begin(),hVect.end(),compare_string1);//aufsteigend nach erstem String sort(hVect.begin(),hVect.end(),inverse(compare_int));//absteigend nach Zahl[/quote]
Sieht gut aus, nur gibt der mir eine Fehlermeldung beim kompilieren:E:\MLS\FileReader\FileReader\FileReaderView.cpp(672) : error C2664: 'void __cdecl std::sort(struct CFileReaderView::LCSTRUCT *,struct CFileReaderView::LCSTRUCT *,bool (__thiscall *)(const struct CFileReaderView::LCSTRUCT &,const struct CFileReaderVi ew::LCSTRUCT &))' : Konvertierung des Parameters 3 von 'bool (const struct CFileReaderView::LCSTRUCT &,const struct CFileReaderView::LCSTRUCT &)' in 'bool (__thiscall *)(const struct CFileReaderView::LCSTRUCT &,const struct CFileReaderView::LCSTRUCT &)' nicht moeglich Keine Funktion mit diesem Namen im Gueltigkeitsbereich stimmt mit dem Zieltyp uebereinAlles ausser 'Verwendung' ist doch in der .h, oder seh ich das falsch?
grüssle

-
Vielleicht hätte ich doch erwähnen sollen, daß du diese Vergleichsfunktionen nicht als (normale) Methoden der View definieren solltest - sort() arbeitet mit binären Funktoren und Funktionszeigern, aber nicht mit Methodenzeigern zusammen.
(also entweder du nimmst eine globale Funktion oder eine statische Methode)
-
Dank, Dank und nochmals Dank, euch allen.
So 'einfach' kann es sein

grüssle

-
So, kommt doch noch ne Frage. Und zwar hab ich das jetzt folgendermassen eingebaut:
Im Header:public: static bool compare_segNmbrAsc(const LCSTRUCT& l,const LCSTRUCT& r ) { return l.vNmbr < r.vNmbr; } static bool compare_segNmbrDesc(const LCSTRUCT& l,const LCSTRUCT& r ) { return l.vNmbr > r.vNmbr; } ...und in der cpp
if ( pNMListView->iSubItem == 0 ) { bDirection1 = (bDirection1) ? false : true; if( bDirection1 ) std::sort( lstVect.begin(), lstVect.end(), compare_segNmbrAsc ); else std::sort( lstVect.begin(), lstVect.end(), compare_segNmbrDesc ); } ...Ist sogar etwas schneller als meine Sortierung

Allerdings sortiert er nach ASCII, also erst Grossbuchstaben, dann die kleinen, dann Umlaute, ...
Habe dann meine eigene Funktion gebastelt, die erst ein MakeLower() macht, und dann die Umlaute bereinigt. Für Deutsch. Es ist aber ein Tool für Übersetzungen. Und da ich keine Lust habe, eine Funktion für jede mögliche Sprache zu erstellen, wollte ich das ganze mit setlocale machen. Aber er macht nichts.
Habe den Header eingebunden und vor den sort setlocale( LC_ALL, "german" ); gesetzt. Ohne Erfolg.
Lt. MSDN sollte es funktionieren?! Tuts aber nicht.
Ist hier noch etwas zu berücksichtigen? Google und die Forumssuche haben mich nicht wirklich weitergebracht.Ok, von der Zeit her wäre meine eigene Lösung noch ok. 100.000 Einträge dauern ohne meine Funktion ca 30 Sek., mit ca 60 Sek.
Aber warum jetzt nicht den ganzen Weg gehen?
grüssle

-
wenn es ein tool ist fuer uebersetzungen (arbeite in der localisierung, uebersetzungen sind mein spezial gebiet)
dann wuerde ich raten das tool direkt Unicode zu erstellen, dann ist das CString auch nicht unicode und vergleicht richtig.
Dann hast du auch keine probleme beim anzeigen der aisatischen sprachen
CHS, CHT, KOR, JPN, THA usw
-
Ist UNICODE. Sortiert trotzdem 'falsch'.
Auch die Files, die bearbeitet werden sind UNICODE( entweder UTF8 oder UTF16 ). Soweit ist alles ok.
Auch das Anzeigen der Daten im ListCtrl ist kein Thema, Chinesisch, Koreanisch, Polnisch, ...
Alles funktioniert.Nur der std::sort ...
grüssle

-
also ich sortiere meine ergebnisse {suche in der datenbank nach uebersetzungen} auch indem ich den strukturen vector das std::sort verpass, und habe ueberhaupt keine probleme dieser art
btw: CString::MakeUpper() sollte mit allen sprachen funktionieren denk ich
-
Bei mir MakeLower(). Ist aber egal. Hauptsache gleichgross

Nur beim Sortieren stellt er sich an wie ein :xmas2:
Deshalb die Frage wegen setlocale.
char* p = setlocale( LC_ALL, "german" );p = "German_Germany.1252".
Aber an dem Sortierchaos ändert das rein garnix
grüssle

-
nur so nebenbei, wenn deine app unicode ist, warum bentzt du ueberall char ?
char ist ANSI, fuer unicode nimmt man wchar_t
ich habs immer so das ich alles in TCHAR schreibe - also auch _T("text") statt "text" oder L"text"
wenn du schon unicode benutzt, sei wenigstens konsequent und benutz es auch durchweg, spaarst dir viel aerger damit
-
Is klar. der char* p oben ist nur zum Testen. Wird eigentlich nicht gebraucht.
CString und _T("bla") rulez ;), oder TCHAR, oder ...
grüssle
