Wiederholt vorkommene Zeichen elemenieren
-
Hallo,
ich muss ein Programm schreiben, dass einen eingegebenen Text auf doppelt vorkommene Buchstaben überprüft und diese eleminiert.
Also falls ich eingebe:
aabbbcddddsoll rauskommen:
abcdIch bin noch ziemlicher Anfänger in C++ und bin bis jetzt soweit gekommen:
Also der eingegebene Text wird in "eingabe" gespeichert.
for (i=0;i<strlen(eingabe);i++)
if (eingabe[i]==eingabe[i+1]) eingabe[i+1] = eingabe[i+2];Durch die Schleife wird zwar aus "aabcd" -> abcd , jedoch nicht aus aaabcd -> abcd sondern aabcd ...
Was mach ich falsch ? Wie kriege ich hin, dass das Programm wenn mehrere Zeichen wiederholt nacheinander Vorkommen diese eleminiert, so das nur unterschiedliche Zeichen auf einander folgen können ?
Danke für eure Hilfe
Gruß
-
Mach das -wie in C++ üblich- mit C++ String (std::string/std::wstring). Da kannst Du dann die Methoden find und erase verwenden.
-
Danke für die schnelle Antwort. Leider habe ich damit noch gar keine Erfahrung. Ist es nicht möglich die Aufgabe zu lösen auf dem Wege wie ich angefangen habe ???
Gruß
-
harry20204 schrieb:
[...]Leider habe ich damit noch gar keine Erfahrung.[...]
Falls Interesse besteht, hier ein paar Links:
http://www.volkard.de/vcppkold/die_klasse_string.html
http://cppreference.com/cppstring/index.html
http://www.kharchi.de/cpp_strings.html#Zeichencodeumwandlung_ASCII_UCS_undharry20204 schrieb:
[...]Ist es nicht möglich die Aufgabe zu lösen auf dem Wege wie ich angefangen habe ???
GrußJo:
Durch die Schleife wird zwar aus "aabcd" -> abcd , jedoch nicht aus aaabcd -> abcd sondern aabcd ...
Dann pack das in eine Funktion/Methode und ruf die rekursiv auf. Damit sollte sich das Problem lösen lassen
.
-
Erstmal danke für die Links .... naja wie gesagt bin ich Anfänger ... ich sitze jetzt seit paar Stunden an dieser "warscheinlich" leichten Aufgabe und bin am Verzweifeln ...Habe schon sämtliche Sachen ausprobiert .... er gibt mir immer wieder das selbe aus. Wenn 2 gleiche Zeichen aufeinander folgen klappt es, wenn mehrere gleiche aufeinander folgen nicht. Kannst du mir nicht vll einfach die Schleife korrigieren ? Mir wäre dadurch sehr geholfen
-
harry20204 schrieb:
Erstmal danke für die Links .... naja wie gesagt bin ich Anfänger ... ich sitze jetzt seit paar Stunden an dieser "warscheinlich" leichten Aufgabe
so leicht ist das gar nicht, wenn man es selber programmiert. Deine korrigierte Schleife sähe vielleicht so aus
#include <iostream> #include <string> int main() { using namespace std; string eingabe; cin >> eingabe; // Lösche alle aufeinanderfolgenden doppelten Zeichen int iEnd = eingabe.size(); int i = 0; for( int ib; (ib = i) != eingabe.size() && ++i != eingabe.size(); ) { if( eingabe[ib] == eingabe[i] ) { for( ; ++i != eingabe.size(); ) if( eingabe[ib] != eingabe[i] ) eingabe[++ib] = eingabe[i]; iEnd = ib + 1; break; } } eingabe.erase( iEnd, eingabe.size() - iEnd ); // Rest löschen cout << "[" << eingabe << "]" << endl; return 0; }einfacher ist es, den unique-Algorithmus aus der STL zu benutzen. Dann sieht's so aus:
#include <iostream> #include <string> #include <algorithm> // unique int main() { using namespace std; string eingabe; cin >> eingabe; // Lösche alle aufeinanderfolgenden doppelten Zeichen eingabe.erase( unique( eingabe.begin(), eingabe.end() ), eingabe.end() ); cout << "[" << eingabe << "]" << endl; return 0; }Gruß
Werner
-
harry20204 schrieb:
...Ist es nicht möglich die Aufgabe zu lösen auf dem Wege wie ich angefangen habe ???
GrußMöglich ist alles.
Aber Du hast die Wahl:- 8 Stunden lang an Deinem Weg rumzubasteln; Ergebnis: Eher gräßlicher Code; Lernfaktor 1 von 10; Code für nicht viel Anderes zu verwenden
- 2 Stunden in STL einarbeiten; Ergebnis: Sehr eleganter Code; Lernfaktor 8 von 10; Code (und STL-Kenntnisse) für viele spätere Projekte weiterverwendbar.
Ich weiß, dass JEDER immer erstmal denkt, seine (meist über blutiges Trial&Error-Fuddeln erarbeitete) Herangehensweise sei die effektiveste und sein Problem sei besonders exotisch .... ich weiß aber auch, dass das in 90% der Fälle nicht stimmt.

Gerade bei solchen "Standardaufgaben" darf man davon ausgehen, dass sehr viele (und darunter sehr viel bessere) Programmierer dafür Lösung erarbeitet haben - und ein Ergebnis davon ist z.B. die STL (und boost).Gruß,
Simon2.
-
harry20204 schrieb:
Ist es nicht möglich die Aufgabe zu lösen auf dem Wege wie ich angefangen habe ???Gruß
mit hilfe der klasse string würds schon n bisschen schöner aussehen aber hier hast du mal n ansatz der auf C-strings basiert, also so wie du die aufgabe schon begonnen hast.
#include <iostream> #include <cstring> using namespace std; bool contains(const char ch,const char* const str) { for (int i=0;str[i]!=0;i++) if (str[i]==ch) return true; return false; }; int main() { char eingabe[100]; char* str=0; cin>>eingabe; str=new char[strlen(eingabe)+1]; //+1 für NUL str[0]=0;// strncat hängt nur an einen nullterminierten String an... for (int i=0;eingabe[i]!=0;i++) { if (!contains(eingabe[i],str)) strncat(str,&eingabe[i],1); else continue; }; cout<<str; delete [] str; };aber achtung: cin liest nur bis zum ersten leerzeichen ein. ich glaube cin.getline() oder so wär eher das richtige dafür. so klappts jedenfalls. der zweite parameter der funktion soll ein readonly zeiger sein und auch der speicherbereich soll "readonly" sein, weiss aber nimmer so genau ob das der richtige weg ist
