Ob Strings anagramm sind? Meine Problemmstellung: zeichen aus string entfernen
-
Grossbuchstaben in Kleinbuchstaben verwandeln. Buchstaben des Wortes sortieren, z.B. aus 'anna' wird 'aann' oder aus 'nana' wird 'aann'. Dann einfach Buchstabenweise vergleichen. Es ist nicht noetig, Buchstaben irgendwie zu entfernen.
-
Danke euch beide für den tipps
ich habe alle schleifen getrennt getestet und alle haben funktioniert.
von 65. Zeile stimmt etwas nicht und leider erkenne ich nicht. könnt ihr mir helfen?
es wird immer false teil in main funktion ausgeführt#include<iostream> using namespace std; #include<cctype> #include<cstring> int isAnagramm(char *str1, char *str2){ int isanagramm = 0; char tmp ; int i = 0; char c; //hier verkleinere ich str1-Buchstaben while (str1[i]){ c=str1[i]; if (isupper(c)){ c=tolower(c); str1[i] = c; } i++; } //hier verkleinere ich str2-Buchstaben while (str2[i]){ c=str2[i]; if (isupper(c)){ c=tolower(c); str2[i] = c; } i++; } //hier sortiere ich str1-Buchstaben for (int i=0;str1[i] != '\0';i++){ for(int j=i + 1;str1[j]!= '\0';j++){ if (str1[j] < str1[j-1]){ tmp = str1[j]; str1[j] =str1[j-1]; str1[j-1] = tmp; } } } //hier sortiere ich str2-Buchstaben for (int i=0;str2[i] != '\0';i++){ for(int j=i + 1;str2[j]!= '\0';j++){ if (str2[j] < str2[j-1]){ tmp = str2[j]; str2[j] =str2[j-1]; str2[j-1] = tmp; } } } while(str1[i] == str2[i] && str1[i] != '\0'){ isanagramm = 1; i++; } return isanagramm; } int main(){ char str1[20]; char str2[20]; cin >> str1; cin >> str2; if(isAnagramm(str1, str2)) cout << "Die sind anagramm\n" ; else cout << "die sind nicht anagramm\n"; return 0; }
-
Edit: Totaler Blödsinn. Man sollte schon den Unterschied zwischen Anagramm und Palindrom kennen
-
Du solltest testen, ob die Strings gleich lang sind. Wenn nicht, dann koennen es keine Anagramme sein.
while(str1[i] == str2[i] && str1[i] != '\0')
Bei deine Fehlerbeschreibung kann ich nur raten, aber was passiert, wenn str1 laenger als str2 ist? Dann kann i ausserhalb von str2 liegen und es kommt zu einer Zugriffsverletzung.
-
ihr seid echt supper.jetzt habe ich von 65. bis 73. zeile das eingebaut und funktioniert
for (int i = 0; str1[i] != '\0'; i++){ if (str1[i] == str2[i]){ isanagramm = 1; }else{ isanagramm = 0; return isanagramm; } }
es ist echt harte weg zu programmierenlernen. Braucht man viel geduld und ausdauer
danke danke nochmals
-
Aller letzte frage für diese Code
bei größere strings funktioneirt nicht, weil das doch nicht komplett sortiertfor (int i=0;str1[i] != '\0';i++){ for(int j=i + 1;str1[j]!= '\0';j++){ if (str1[j] < str1[j-1]){ tmp = str1[j]; str1[j] =str1[j-1]; str1[j-1] = tmp; } } }
ich habe mit zahle am zettel ausprobiert und das macht nur so
eingabe -> 8, 7,6, 1
7 , 8, 6, 1
7, 6, 8, 1
7, 6, 1, 8
7,1,6,8ich habe echt viel zeit damit verbracht und habe sogar string sortieren in c++ gesucht und finde nichts gescheites
-
Dein Algorithmus sortiert den String in der falschen Reihenfolge, d.h. du sortierst von rechts nach links. Deine Schleifen gehen aber davon aus, dass die Sortierung von links nach rechts verläuft. Am Ende des ersten Durchlaufs steht an der letzten Stelle des Strings der richtige Buchstabe, nicht an der ersten. Die Schleife läuft im zweiten Durchlauf aber ab dem zweiten Buchstaben, obwohl der erste nicht an der richtigen Position steht.
Entweder baust du die Schleifen um, sodass sie von hinten nach vorne laufen, oder du verschiebst den kleineren Buchstaben nach vorn (im Moment verschiebst du den größeren nach hinten).
-
khati, du solltest dir angewöhnen, nicht so lange funktionen zu bauen, die
gleich 3 dinge auf einmal tun. Erst wandelst du alles in Kleinbuchstaben um,
dann sortierst du die einzelnen Zeichen und dann vergleichst du die Ergennisse.
Und genauso solltest du das auch aufteilen in mehrere Funktionen. Das ist dann
auch leichter nachvollziehbar; denn jeder Schritt bekommt so seinen Namen (als
Funktionsname).Wenn du jetzt noch "richtig C++" und nicht nur "C in C++" programmieren
würdest, wär das alles noch viel einfacher:#include <cctype> #include <algorithm> #include <string> void toLowerAndSortInplace(std::string & s) { std::transform(s.begin(),s.end(),s.begin(),std::tolower); std::sort(s.begin(),s.end()); } bool isAnagram(std::string s1, std::string s2) { if (s1.length() != s2.length()) return false; toLowerAndSortInplace(s1); toLowerAndSortInplace(s2); return s1 == s2; }
(ungetestet)
-
@ krümelkacker: danke für den tipp. ich lerne gerade programmieren und daher darf ich nicht solche bibliotheken benutzen. Ich habe jede schleife getrennt getestet und hat für sehr kleine strings funktioniert und dann habe ich zusammen eingebaut
ich werde versuchen so einzubauen wie DocShoe mir empfolen hat
-
#include <iostream> // Ermittelt die Länge des Strings std::size_t getLen(const char *str) { std::size_t len = 0; // String wird durch NULL terminiert while (str[len] != NULL) { ++len; } return len; } // Überprüft ob zwei Strings identisch sind bool isEqual(const char *str1, const char *str2) { std::size_t len1 = getLen(str1); std::size_t len2 = getLen(str2); // Wenn die Länge nicht gleich ist, kann der Rest auch nicht mehr identisch sein if (len1 != len2) { return false; } for (std::size_t i = 0; i < len1; ++i) { if (str1[i] != str2[i]) return false; } return true; } // Wandelt den gesamten String in Kleinbuchstaben um void strToLower(char *str) { std::size_t len = getLen(str); for (std::size_t i = 0; i < len; ++i) { if (isupper(str[i])) { str[i] = tolower(str[i]); } } } // Tauscht ein Zeichen aus (Dreieckstausch) void chSwap(char *a, char *b) { char t = *a; *a = *b; *b = t; } // Sortiert den String (Bubblesort: sehr langsam, aber einfach) void strSort(char *str) { std::size_t len = getLen(str); bool again; do { // Schleife wird so lange wiederholt bis kein Tausch mehr stattfindet again = false; for (std::size_t i = 0; i < len - 1; ++i) { if (str[i] > str[i + 1]) { // Zeichen austauschen chSwap(&str[i], &str[i + 1]); again = true; } } } while (again); } // Macht die eigentliche Überprüfung bool isAnagram(char *str1, char *str2) { strToLower(str1); strToLower(str2); strSort(str1); strSort(str2); return isEqual(str1, str2); } int main() { const int MAX_BUF_SIZE = 256; char str1[MAX_BUF_SIZE] = {}; // Setzt alles auf NULL char str2[MAX_BUF_SIZE] = {}; // Setzt alles auf NULL // Liest MAX_BUF_SIZE - 1 Zeichen ein, um noch Platz für das NULL zu haben std::cin.getline(str1, MAX_BUF_SIZE - 1); std::cin.getline(str2, MAX_BUF_SIZE - 1); if (isAnagram(str1, str2)) { std::cout << "Anagramm!\n"; } else { std::cout << "Kein Anagramm!\n"; } return 0; }
Hier mal ein umfassenderes Beispiel, wie ich es lösen würde, wenn ich es lösen müsste.
Du musst dabei immer im Hinterkopf behalten, dass das in C++ mit std::string um einiges schöner, einfacher und auch sicherer geht.
Der Code nutzt (außer für die Ausgabe) keine Funktionen aus der Standardbibliothek.
-
@jhkjhk: Geht das noch umständlicher?
So hätte ich das gemacht:bool isAnagramm(const char *str1, const char *str2) { int cnt[255] = {}; while (*str1) ++cnt[tolower(*str1++)]; while (*str2) --cnt[tolower(*str2++)]; for (int i=0; i<255; ++i) if (cnt[i]) return false; return true; }
-
meine Endversion. Funktioneirt komplett. Seit heute in der fruh sitze ich daran
Danke an alle die mir geholfen haben#include<iostream> using namespace std; #include<cctype> #include<cstring> int getLen(char *str){ int len = 0; for(int i = 0; str[i]!= '\0'; i++){ len +=1; } return len; } bool isEqualLen(char *str1, char *str2){ int len1 = getLen(str1); int len2 = getLen(str2); if(len1 != len2){ return false; } return true; } void toLowerAndSortInplace(char *str){ char tmp ; int i = 0; char c; //hier verkleinere ich str2-Buchstaben while (str[i]){ c=str[i]; if (isupper(c)){ c=tolower(c); str[i] = c; } i++; } //hier sortiere ich str2-Buchstaben for (int i=0;str[i] != '\0';i++){ for(int j=i + 1;str[j]!= '\0';j++){ if (str[i] > str[j]){ tmp = str[j]; str[j] =str[i]; str[i] = tmp; } } } } bool isAnagram(char *str1, char *str2){ toLowerAndSortInplace(str1); toLowerAndSortInplace(str2); bool isAnagramm = true; if(isEqualLen == false){ isAnagramm = false; return isAnagramm ; }else { for (int i = 0; str1[i] != '\0'; i++){ if (str1[i] == str2[i]){ isAnagramm = 1; }else{ isAnagramm = 0; return isAnagramm; } } } return isAnagramm; } int main(){ char restart; do { char str1[20]; char str2[20]; cin >> str1; cin >> str2; if(isAnagram(str1, str2)) cout << "Die sind anagramm\n" ; else cout << "die sind nicht anagramm\n"; cout << endl; cout << "Wollen Sie das Programm nochmal starten? (y/n) "; cin >> restart; cout << endl; } while (restart == 'y'); cout << "Bis zum naechsten Mal " << endl; return 0; }
-
khati:
Bitte benutzstd::cin.getline
ansonsten bekommst du Probleme mit Leerzeichen, also mit längeren Sätzen.Oder sollen es wirklich nur einzelne Wörter seien?
-
Danke vielmals