Ob Strings anagramm sind? Meine Problemmstellung: zeichen aus string entfernen



  • 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 sortiert

    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;  
              				  }
        				}
    
    			}
    

    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,8

    ich 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 benutz std::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


Anmelden zum Antworten