String am Speicherplatz umkehren
-
Soo kein Tag an dem ich nicht irgendwas programmiere und das Chaos ausbricht

Heute hab ich versucht folgende Aufgabe zu lösen:
Schreiben Sie eine Funktion, die einen String an seinem Speicherplatz umkehrt, dh ohne alle Zeichen zu duplizieren. Der Funktion wird ein Zeiger auf den String übergeben.
Mit einem Kumpel zusammen kamen wir auf folgende Lösung aber die war wohl eher geraten als gekonnt. OK sie geht aber keiner von uns weiss so richtig wieso
Hier mal der Quellcode
#include <iostream.h> #include <conio.h> #include <string.h> void umkehren(char *inhalt) { char temp; for(int i=0; i<strlen(inhalt)/2; i++) { temp = inhalt[i]; inhalt[i] = inhalt[strlen(inhalt) – i -1]; inhalt[strlen(inhalt)-i -1] = temp; } } int main() { char string[]="ollah"; umkehren(string); cout << string; getch(); return 0; }Was unklar ist, wieso funktioniert das nur wenn man /2 macht und wieso nur wenn -i -1 ?? Lässt man da nur eines von beiden Weg oder ändert es geht gar nichts mehr. Kann das vielleicht mal einer Erläutern wäre echt spitze. Ich versuch das (im Gegensatz zu anderen) nämlich zu verstehen
-
nunja du vertauscht ja das erste mit dem letzten, dann das 2te mit dem vorletzten usw in deiner schleife. das heisst wenn du in der mitten ankommst hast du die die nach der mitte kommen doch schon vertauscht. Folglich musst auch auch nur bis zur mitte iterieren, also genau length/2.
Wenn dir die -1 unklar ist schau dir mal an was bei den einzelnen schleifendurchläufen passiert.
mit inhalt[strlen(inhalt)] = temp; würdest du ja auf inhalt[length] zugreifen, also bei eine länge von 7 auf das inhalt[7]. Dies ist aber genau ein Element zu weit denn da bei 0 angefangen wird zu zählen gehts nur bis inhalt[6]. daher das "-1". Nun kommt -i weil du ja das erste mit dem letzen also inhalt[size-i ( was null ist) -1] vertauscht. um beim zweiten durchlauf auf das vorletze zu kommen wird i ja 1 also inhalt[size-1-1] also genau das vorletzte element. dies läuft dann so weiter bis man die mitte erreicht.
-
Die Grenze mußt du auf Länge/2 setzen, weil du die Zeichen sonst doppelt gegeneinander vertauschst (1<->n, 2<->n-1, ..., n/2<->n/2+1 (hier bricht deine Schleife ab - korrekt), n/2+1<->n/2,... n<->1 (das würde alles wieder zurücktauschen).
und das "-1" ist wichtig, damit du innerhalb der Grenzen deines Strings bleibst (das erste Zeichen steht bei inhalt[0], das letzte bei inhalt[strlen(inhalt)-1], inhalt[strlen(inhalt)] ist das Begrenzungszeichen '\0').
PS: verwende besser <iostream> und <cstring> anstelle der <*.h> Header

PPS: Eine Optimierung wäre es noch, die Länge einmal am Anfang zu berechnen.
-
Danke
-
Ich liebe dieses Forum, viel Dank für die schnell Antwort.
Mir schwebt da irgendwie vor Augen dass es da auch eine andere Lösung gibt mit Variablen. Also das man im Schleifendurchgang jeden Wert [i] in eine Variable speichert und dann das irgendwie rückwärts wieder ausgibt. Dazu müssten ja glaub ich 2 Variablen reichen. Aber momentan weiss ich nicht so genau ob das geht und wie.
Vielleicht kann mir da auch einer sagen ob das geht...evtl. mit nem kleinen Codefragment
-
Edit: Gelöscht Viel zu langsam
-
Ich fürchte, zwei Variablen reichen nicht aus, um (theoretisch) beliebig viele Zeichen unterzubringen (außer du verwendest std::string, da reicht schon eine ;)).
PS: noch ein etwas kürzerer Code ;):
#include <algorithm> void umkehren(char*inhalt) { std::reverse(inhalt,inhalt+strlen(inhalt)); }PPS: Dein Code sieht aber schon beinahe optimal aus - nur die strlen-Berechnung würde ich nach vorne ziehen:
void umkehren(char *inhalt) { size_t len=strlen(inhalt); char temp; for(int i=0; i<len/2; i++) { temp = inhalt[i]; inhalt[i] = inhalt[len – i - 1]; inhalt[len - i -1] = temp; } }
-
Hier ne allgemeine Version. Ich glaube da sieht man auch besser, dass es funktioniert. Wenn man die Funktino (ohne templäd) nur für strings machen würde kann man den elementCount Parameter nat. weglassen.
//Die allgemeine version template<typename T> void arrayUmkehren(T* array, unsigned int elementCount) { T* anfang = array; T* ende = array + elementCount - 1; while (anfang < ende) { std::swap<T>(*anfang, *ende); //schon klar braucht auch eine tempVariable ;) anfang++; ende--; } }Aufruf wäre dann so:
char string[]="ollah"; arrayUmkehren<char>(string, strlen(string)); cout << string;
-
templäd schrieb:
Hier ne allgemeine Version. Ich glaube da sieht man auch besser, dass es funktioniert.
klar, warum standard algorithmen nehmen, wenn man es auch umständlich selbst machen kann...
