Doppelte (bzw. mehrfach) Vorkommende Leerzeichen in std::string löschen?
-
Michael E. schrieb:
Na wir wollen doch fair bleiben und deiner Version auch mal das Erzeugen eines std::strings beibringen (so wie es gefordert war):
...
Ergebnis (VS 2008 Release, volle Optimierung):
687 (deins) gegen 579 (meins)Und die Moral von der Geschicht: Wenns schnell sein soll, nimm std::string nicht.
-
Next Generation Hacker schrieb:
Und die Moral von der Geschicht: Wenns schnell sein soll, nimm std::string nicht.
#define _SECURE_SCL 0 #include <iostream> #include <string> #include <algorithm> #include <windows.h> using namespace std; void remove_spc (char *s) { char *t = s; char l = 0; while (*s) { if (*s != ' ' || l != ' ') *t++ = *s; l = *s++; } *t = 0; } char *hacker() { char* a = new char[100]; strcpy (a, "a b c d e f g "); remove_spc (a); return a; } bool isDoubleSpace(char first, char second) { return first == second && second == ' '; } string michael() { string foo = "a b c d e f g "; string::iterator newEnd = unique(foo.begin(), foo.end(), isDoubleSpace); foo.resize(newEnd - foo.begin()); return foo; } int main () { UINT32 t1, t2; #define COUNT 1000000 t1 = GetTickCount(); for (int s=0; s<COUNT; s++) hacker(); t1 = GetTickCount() - t1; t2 = GetTickCount(); for (int s=0; s<COUNT; s++) michael(); t2 = GetTickCount() - t2; cout << t1 << endl; cout << t2 << endl; }Hacker 266ms
Michael 327ms
-
Ich warte aber definitiv lieber ne Sekunde bei der Ausführung als mich wochenlang bei der Entwicklung mit rohen char-Arrays rumzuplagen :p
-
[quote="life"]...[/cpp]
Speicherloch?life schrieb:
[cpp]
#define _SECURE_SCL 0[/cpp]
Ja!for (int s=0; s<COUNT; s++) delete hacker();Kannste damit nochmal messen?
-
Mit delete[] braucht er nur noch ~202ms. Da müsste man sich vlt mal den asm code anschauen..
-
Michael E. schrieb:
Ich warte aber definitiv lieber ne Sekunde bei der Ausführung als mich wochenlang bei der Entwicklung mit rohen char-Arrays rumzuplagen :p
Sowas hört man sonst nur von Java-Programmierern.

-
volkard schrieb:
for (int s=0; s<COUNT; s++) delete hacker();Volkard meinte bestimmt
for (int s=0; s<COUNT; s++) delete[] hacker();Macht aber vermutlich keinen Fehler auf MSVC. Nett, daß delete so schnell ist.
-
volkard schrieb:
Nett, daß delete so schnell ist.
So schnell, dass die Ausführung der Anweisung sogar Zeit einspart anstatt welche zu verbrauchen?

-
life schrieb:
volkard schrieb:
Nett, daß delete so schnell ist.
So schnell, dass die Ausführung der Anweisung sogar Zeit einspart anstatt welche zu verbrauchen?

Cache-Effekte, hoffe ich. Oder der Funny MSVC hat wiedermal endeckt, daß ein unbedingtes new/delete-Paar mit nur Drinnenrumschreiben ohne Ergebnis da ist, und hat es wegoptimiert.
-
Wie wärs mit einer trivialen Lösung:
void remove_c ( string& s, char c ) { unsigned i, j, k, n; k = n = s.size(); for ( i = 0, j = 0; i < k; i++ ) { if ( s[i] != c ) s[j] = s[i], j++; else n--; } if ( k != n ) s.resize ( n ); } int main() { string s = " B en c h m ark - th is, b ro t he r! "; remove_c ( s, ' ' ); cout << s << endl; return 0; }Gruß,
B.B.
-
Naja, erstens löschst du alle Leerzeichen und nicht, wie gefordert, alle doppelten Leerzeichen. Zweitens ist dein Algorithmus im Prinzip gleich den anderen vorgestellten Lösungen und drittens hast du die komplizierteste Darstellung

-
Noob Otto schrieb:
... oder doch nicht? Wenn ich das, was Michael E. geschrieben hat, in eine Funktion packe und dann mit meiner Funktion vergleiche, ist meine schneller. Ich verstehe die Welt nicht mehr!

Da machst du ziemlich sicher was falsch, kannst uns mal zeigen wie du misst?

@ Big Brother & N.G. Hacker:
schaut euch doch mal an was std::unique macht bevor ihr eure eigenen Implementierungen davon schreibt
-
btw:
hat eigtl keiner mitbekommen, dass der code von blue irgendwas da oben nen fehler enthält? ^^
s.erase(newEnd, s.begin());
sieht nicht wirklich richtig aus
bb
-
Blue-Tiger schrieb:
@ Big Brother & N.G. Hacker:
schaut euch doch mal an was std::unique macht bevor ihr eure eigenen Implementierungen davon schreibtDie Lösung von Michael E. ist die beste und schnellste, wenn man mit std::string arbeiten muss. Schneller gehts nur mit char[], also völlig ohne std::string. Kann man std::unique auf char[] anwenden?
-
Klar. Das ist ja das schöne an den generischen Implementierungen:
char foo[20]; unique(foo, foo + 20);
-
Next Generation Hacker schrieb:
Kann man std::unique auf char[] anwenden?
Ja, denn die STL-Algorithmen arbeiten auf Iteratorenbasis. Dabei ist egal, wohin der Iterator zeigt und was für einen Typen er hat, sofern er die erforderten Konzepte (z.B. Random Access) unterstützt.
char*kann auch als Iterator eingesetzt werden, d.h. man übergibtstd::unique()zwei Zeiger auf Beginn und Ende der Sequenz. Dafür brauchts nicht einmal eine Nullterminierung.