Sortieren von Zeichen
-
In der Angabe steht eigentlich, dass du einen string mit new erstellen sollst und nicht ein char array.
Wenn du einen char* oder string* zurückgeben willst, dann sollte der Rückgabewert auch davon sein und nicht int.
Wenn du dann einen Zeiger auf den string zurück gibst, dann ist das auch kein Zeiger auf eine lokale Variable, weil du den string ja mit new erstellt hast.
Das delete solltest du auch erst machen, wenn du den string nicht mehr brauchst, also wenn du den string auch außerhalb der funktion nicht mehr brauchst.
-
geändert:
string* ziel= new string[laenge];geändert:
string* sortstring(string); string* sortstring(string) { ... }das mit
delete[] ziel;nachdem ich den nicht mehr brauche, funktioniert nicht, sagt nicht deklarierte variable.
Wie macht man das mit der pointer Übergabe?
ich kriege das immer noch nicht auf die Reihe.
-
du gibst ja nicht den "ziel" pointer zurück, sondern den wert (Adresse vom mit new erstellten string) den "ziel" enthält.
string* sortstring(string) { string* ziel= new string[laenge]; //... return ziel; } string* bla = sortstring(intext); //tuwas mit bla delete bla;
-
außerdem:
kein array von string
sondernstring* ziel= new string();
-
Überraschungsgast schrieb:
In der Angabe steht eigentlich, dass du einen string mit new erstellen sollst und nicht ein char array.
Hast recht, aber gemeint war sicherlich char*. Abgesehen davon hat das Array die falsche Länge.
Der Tip mit dem 256-er-Array zielt wahrscheinlich darauf ab, buchzuführen, welche Zeichen vorkommen. Das kann man sich auch einfacher machen:
char* sortstring(string const& quelle) { bool existing_chars[256] = {false}; size_t new_len = 0; for (string::const_iterator i = quelle.begin(); i != quelle.end(); ++i) { size_t chr = static_cast<size_t>(*i); if (not existing_chars[chr]) ++new_len; existing_chars[chr] = true; } char* ziel = new char[new_len]; char* c = ziel; for (size_t i = 0; i < 256; ++i) if (existing_chars[i]) *c++ = static_cast<char>(i); return ziel; }(Ungetestet.)
Einfacher geht das mit einer std::map. Aber das Prinzip bleibt dasselbe.
Übrigens hast Du recht: Das Zurückgeben solch eines Zeigers ist schlechter Stil, da fehleranfällig (und unnötig: wozu gibt's die String-Klasse?), aber nicht aus dem von Dir genannten Grund, denn der Zeiger zeigt nicht auf lokalen Speicher, sondern auf Heap-Speicher.
-
deine Variante verstehe ich leider nicht so ganz,
Ich schreib mal zu jeder zeile ein Kommentar bitte korrigiert mich wenns nicht stimmt.char* sortstring(string const& quelle) { //const referenz von quelle auf einen string //ausserdem wird hier die funktion sortstring ( die auf einen char zeigt) definiert, kann mir darunter sehr wenig vorstellen bool existing_chars[256] = {false}; // array anlegen um existrierede Zeichen später nur einmal zu schreiben size_t new_len = 0; // definieren der längenvariable for (string::const_iterator i = quelle.begin(); i != quelle.end(); ++i) { // Schleife um size_t chr = static_cast<size_t>(*i); // hier verstehe ich nicht wieso du es in den size_t typ casten tust ( evlt. wird später was mit länge verglichen?!weil ja length(); den Rückgabewert hat) if (not existing_chars[chr]) //wenn an dieser stelle kein Zeichen ( true) vorhanden ist wird ++new_len; // wird die länge erhöht(prefix-increment der Länge) existing_chars[chr] = true; // und das Zeichen wird abgehackt das es schon benutzt wurde } char* ziel = new char[new_len]; // speicher im heap reservieren char* c = ziel; // einen Zeiger auf ziel ( den Speicher im Stapel) for (size_t i = 0; i < 256; ++i) // forschleife um auf charwerte zu casten if (existing_chars[i]) // wenn einer gefunden *c++ = static_cast<char>(i); wird i gecastet wieso aber auf den *c und nicht direkt auf *ziel und aus welchem grund wird hier inrekemtiert?? return ziel; }viele fragen hab ich wa

schönen abend noch
-
Hallo junger Padawan,
ich mach's mir mal einfach und verzichte auf die ganzen Code-Tags beim Durchgehen des Codes:
char* sortstring(string const& quelle)Du übergibst den String direkt. Dadurch wird eine Kopie des Strings erzeugt. 'string const&' ist letztendlich dasselbe, nur dass keine Kopie des Strings erzeugt werden muss, weil auf das Original verwiesen wird.
Wenn ihr noch keine Referenzen kennt, lass das einfach weg.
size_t chr = static_cast<size_t>(*i); // hier verstehe ich nicht wieso du es in den size_t typ casten tust'*i' ist ein Zeichen des Strings. Dieses Zeichen wollen wir als Index für das Array verwenden. Ich sträube mich dagegen, einen char als Ganzzahl zu betrachten (auch wenn das in C++ nunmal so ist), daher caste ich das ganze explizit in einen Ganzzahltypen.
*c++ = static_cast<char>(i); wird i gecastet wieso aber auf den *c und nicht direkt auf *ziel und aus welchem grund wird hier inrekemtiert??Was hier passiert, ist folgendes:
Wir haben unseren Speicher reserviert und 'ziel' verweist darauf. Jetzt müssen wir diesen Speicher Zeichen für Zeichen durchgehen und an der jeweiligen Stelle das nächste Zeichen abspeichern. Das zeichenweise Durchgehen machen wir uns einfacher (gut, Ansichtssache), indem wir zuerst einen Zeiger auf den Beginn zeigen lassen ('c'), und diesen Zeiger dann immer erhöhen, dass er auf das nächste Element zeigt. Direkt vor der Erhöhung des Zeigers schreiben wir an die aktuelle Speicheradresse aber noch das aktuelle Zeichen. Das geschieht durch das '*c++ = zeichen'. Man könnte das auch ausführlich schreiben, nämlich so:
*c = zeichen; ++c; // Speicherindex erhöhen.In jedem Fall ist das aktuelle Zeichen gegeben durch 'static_cast<char>(i)'.
-
Mal ne Frage ... dürft ihr alle Funktionen des Standards nutzen?
#include <algorithm> #include <string> std::string sortstring(std::string string) { std::string* copy(new std::string(string)); std::sort(copy->begin(), copy->end()); std::unique(copy->begin(), copy->end()); return copy; }Ist zwar etwas unperformant aber einfach

int main() { std::cout << "Bitte Quelltext: "; std::string input; std::getline(std::cin, input); std::string* ptr_sort(sortstring(input)); std::cout << "Sortierte Ausgabe: " << *ptr_sort << std::endl; delete ptr_sort; }... naja den Prof kannst du übrigens direkt in die Tonne kloppen ...
-
(D)Evil schrieb:
naja den Prof kannst du übrigens direkt in die Tonne kloppen ...
Warum immer so negativ? Solchte Problemstellungen sind an sich doch ganz gut geeignet, um algorithmisches Denken beizubringen. Gut, dass C++ hierfür nicht unbedingt geeignet ist, ist eine andere Sache. Aber nicht jeder will mit einer funktionalen Sprache anfangen.
-
(D)Evil schrieb:
Mal ne Frage ... dürft ihr alle Funktionen des Standards nutzen?
#include <algorithm> #include <string> std::string sortstring(std::string string) { std::string* copy(new std::string(string)); std::sort(copy->begin(), copy->end()); std::unique(copy->begin(), copy->end()); return copy; }Ist zwar etwas unperformant aber einfach

huch?
den code hast du anscheinend nicht ausgiebig getestet
std::string * sorstring (...) //... copy.erase (std::unique(copy.begin(), copy.end()), copy.end());oder
std::string* sortstring(std::string string) { std::sort(string->begin(), string->end()); std::string *copy = new string; std::unique(copy->begin(), copy->end(), back_inserter(*copy)); return copy; }ist auch nicht performant, aber funktioniert immerhin

-
Ja auch gut
Ich teste die Codes leider nie wenn ich was ins Forum schreibe ... geht auch so gut wie immer gut
Nur diesesmal scheinbar nicht.
-
(D)Evil schrieb:
Mal ne Frage ... dürft ihr alle Funktionen des Standards nutzen?
Ich denke nicht, static_cast kennt er nichtmal (darauf wurde er letztens von jemanden angesprochen, und musste zugeben das nicht zu kennen, genauso wie er <algorithm> nicht kennt)
also ich denke in Klausuren ist es besser auf das zu setzen was er kennt sonst gibt das vllt. Probleme.(D)Evil schrieb:
... naja den Prof kannst du übrigens direkt in die Tonne kloppen ...
oh wie Recht du hast
(kannst du Gedanken lesen?)danke für eure Hilfe
-
junger_padawan schrieb:
(D)Evil schrieb:
... naja den Prof kannst du übrigens direkt in die Tonne kloppen ...
oh wie Recht du hast
(kannst du Gedanken lesen?)Glaube ich weniger - aber schon die Aufgabenstellung "mit Hilfe von new..." deutet darauf hin, daß er wenig Ahnung hat von C++.
Randfrage: Welche Teile von C++ kennt der Professor überhaupt? string scheint dabei zu sein, wie sieht es mit anderen STL-Containern aus?
string sortstring(const string& input) { set<char> sorted(input.begin(),input.end()); return string(sorted.begin(),sorted.end());//ich benutze bewußt KEIN new }
-
die aufgabe ist nicht grad die hohe kunst der programmierung. das scheint aus nem grundlagen kurs für studienanfänger zu stammen. da muss man davon ausgehen, dass einige hörer das erste mal in ihrem leben etwas mit programmiersprachen zu tun haben. entsprechend simpel sind die aufgaben formuliert und dementsprechend "naiv" sind die lösungsvorgaben.
in der aufgabe geht es darum, sich gedanken zu machen, was ein string ist, wie man an die einzelnen bestandteile herankommt und wie grundlegend daten sortiert werden können. der prof hat hier einen sehr einfach ansatz vorgegeben, sich lediglich auf 8 bit zeichen zu beschränken und lenkt in die richtung, bucketsort zu verwenden.
würd mich einfach daran orientieren und lieber hinweise in den code schreiben, was an dieser lösung ungünstig ist, anstatt einfach einen "besseren" code abzuliefern. maximal als alternative.
-
junger_padawan schrieb:
(D)Evil schrieb:
Mal ne Frage ... dürft ihr alle Funktionen des Standards nutzen?
Ich denke nicht, static_cast kennt er nichtmal (darauf wurde er letztens von jemanden angesprochen, und musste zugeben das nicht zu kennen, genauso wie er <algorithm> nicht kennt)
also ich denke in Klausuren ist es besser auf das zu setzen was er kennt sonst gibt das vllt. Probleme...Das Problem mit Dozenten sowie Lehrern ist zumeist das sie einmal gelernt haben und damit meinen es zu beherrschen (ich kenne Ausnahmefälle, aber die Aussage trifft auf den Großteil derer zu die ich bisher im Informatikbereich kennen gelernt habe). Nun ist es so das einige vor dem Verabschieden des C++98 Standes C++ gelernt haben, und nach dem (alten) Stand lehren.
Dabei gibt es ganz gravierende Unterschiede im Pre-Standard zum Standard, die sich auch auf Fehlerhandling beziehen. Heutzutage ist zum Beispiel aktiviertes Exceptionhandling und RTTI der Standard, mit entsprechenden Auswirkungen. Gravierendes Beispiel:
int main() { // Behandlung von fehlgeschlagenen new in Pre-Standard: int* a = new int; if(!a) ; // <-- Hier Fehlerbehandlung // Nach dem Standard wird sich aber hier das Programm verabschieden, // wenn nicht zufälligerweise irgendwo eine exception gefangen wird... try { int* a = new int; ; // <-- Hier kommt er nur hin, wenn new erfolgreich war } catch(std::bad_alloc& exp) { // Fehlerbehandlung } }Jeder Dozent/Lehrer sollte sich zumindestens alle 2-3 Jahre mal über Änderungen informieren, sofern er in einem sehr schnelllebigen Bereich (wie Informatik) arbeitet.
cu André
-
Yo, sieht man ja daran, das hin und wieder jemand mit .h-Standard-Headern ankommt. Seit 10 Jahren obsolet. Man muß sich mal 10 Jahre vorstellen, im PC-Bereich.