# Anagramm



## iks (16. Feb 2012)

Guten Tag!

Ich habe mich zu Übungszwecken an einem Programm versucht, das feststellen soll, ob die beiden Übergebenen Strings ein Anagramm sind, also ob sie aus den gleichen Buchstaben bestehen.
Die Lösung aus dem Buch kann ich nicht nachvollziehen, ich wüsste gerne, wo in meiner Lösung der denkfehler liegt. Meine Idee war es, mit 2 verschachtelten for-Schleifen zu arbeiten, sodass fuer den ersten Buchstaben des ersten Strings alle Buchstaben des 2. Strings durchgetestet werden, aber irgendwie funktioniert es nicht, obwohl es doch ganz simpel sein muss. *Brett vorm Kopf*, HEUL!!!
Hier der Code:


```
public static boolean istAnagramm(String s1, String s2) {
		
		boolean ergebnis = true;
		
		if (s1.length() != s2.length()) {
			ergebnis = false;
			return ergebnis;
		} // Ende if
	
		else {
			
			for(int i=0 ; i < s1.length(); i++) {
										
				for(int j=0; j < s1.length(); j++ ) {
					
					if (s1.charAt(i) == s2.charAt(j)) {
						ergebnis = true;
						
					} // Ende if
		
					else ergebnis = false;
					
				} // Ende innere for-Schleife
						
			} // Ende auessere for-Schleife			
				
		} // Ende else
		
		return ergebnis;
		
	} // ende istAnagramm()
```

Aufgerufen wirds in meiner main so:
System.out.println(istAnagramm("all" , "lla"));

ergebnis sollte also "true" sein, es funktioniert aber nicht, kann mir jemand auf die Sprünge helfen?


----------



## Andgalf (16. Feb 2012)

Nur kurz draufgeschaut, aber ich denke die innere Schleife sollte anders rum laufen .... also vom Ende des Strings zum Anfang


----------



## iks (16. Feb 2012)

Oh je, es funktioniert, wenn die innere Schleife anders herum läuft, ich verstehe jedoch nicht, wieso das in in diesem Fall einen Unterschied macht...
Ob ich nun das wort von vorn nach hinten oder hinten nach vorn pruefe, wo ist da der Unterschied, der uebereinstimmende Buchstabe sollte doch so oder so gefunden werden oder nicht?
Hmm, vielleicht muss ich das nochmal mit Stift und Zettel durchgehen...


----------



## fibeline (16. Feb 2012)

Habs mal durchlaufen lassen, und bei mir funktioniert es. Was genau klappt denn bei dir nicht?


----------



## SlaterB (16. Feb 2012)

wichtig: nicht bei jeder einzelnen Übereinstimmung auf true setzen,
sondern mit true beginnen und einer Nicht-Übereinstimmung auf false setzen, 
dann kann eigentlich auch schon abgebrochen werden


----------



## iks (16. Feb 2012)

Also ob ich das vorher auf true setze oder falsch und umgekehrt prüfe macht bei mir keinen Unterschied aus, zumindest nicht im Ergebnis.
Mag sein, dass es saubererer Stil ist, es erst auf true zu setzen, dass weiss ich nicht. Aber mit 2 hochzaehlenden Schleifen klappt es auch nicht, wenn ich ich vorher auf true setze und die if-pruefung umkehre(!=) ....
Wie auch immer, es funktioniert ja mit der runterzaehlenden for-Schleife und ich werde heute Abend mit stift und zettel nachvollziehen, warum das der Fall ist
Daher auf jeden Fall: Großes Dankeschön!


----------



## SlaterB (16. Feb 2012)

auf die Schleife solltest du wirklich achten, stell dir vor bei 6 Buchstaben ergeben die ersten 5 Vergleiche keine Übereinstimmung,
der 6. aber schon, dann ist true das falsche Endergebnis


----------



## iks (16. Feb 2012)

istAnagramm("aaa355bbb" , "bbbaaa553");

Das waere ja aber in diesem Fall oben der Fall...und dennoch funktionierts...oder verstehe ich da wieder was falsch, hrm, vielleicht bin ich heute auch einfach zu muede zu denken.
In welchem Fall sollte es denn nicht funktionieren, wenn ich den boolean vorher auf true setze?


----------



## iks (16. Feb 2012)

Also das ist jetzt mein endgueltiger code und der funktioniert fuer alle meine getesteten Anagramme:


```
public static boolean istAnagramm(String s1, String s2) {
		
		boolean ergebnis = true;
		
		if (s1.length() != s2.length()) {
			ergebnis = false;
			return ergebnis;
		} // Ende if
	
		else {
			
			for(int i=0 ; i < s1.length(); i++) {
										
				for(int j=s1.length()-1; j > 0; j-- ) {
					
					if (s1.charAt(i) == s2.charAt(j)) {
						ergebnis = true;
						
					} // Ende if
		
					else ergebnis = false;
					
				} // Ende innere for-Schleife
						
			} // Ende auessere for-Schleife			
				
		} // Ende else
		
		return ergebnis;
		
	} // ende istAnagramm()
```


----------



## iks (16. Feb 2012)

SORRY, funktioniert natuerlich nicht;(
ohmann, hehe , sekunde ich tests nunmal anders herum


----------



## iks (16. Feb 2012)

Hmm war es so gemeint:


```
public static boolean istAnagramm(String s1, String s2) {
		
		boolean ergebnis = false;
		
		if (s1.length() != s2.length()) {
			ergebnis = false;
			return ergebnis;
		} // Ende if
	
		else {
			
			for(int i=0 ; i < s1.length(); i++) {
										
				for(int j=s1.length()-1; j > 0; j-- ) {
					
					if (s1.charAt(i) != s2.charAt(j)) {
						ergebnis = false;
						
					} // Ende if
		
					else ergebnis = true;
					
				} // Ende innere for-Schleife
						
			} // Ende auessere for-Schleife			
				
		} // Ende else
		
		return ergebnis;
		
	} // ende istAnagramm()
```

...funktioniert bei mir nämlich auch nicht...ich gebs auf, war mein ansatz denn so falsch??!!


----------



## SlaterB (16. Feb 2012)

bei istAnagramm("aaa355bbb" , "bbbaaa553"); wird true zurückgegeben, weil der letzte Vergleich b mit b true ergibt,
allerdings ist aaa355bbb kein Anagramm von bbbaaa553,

bzw. schon, im Sinne von


> Der Begriff Anagramm (von griechisch anagraphein ‚umschreiben‘) bezeichnet ein Wort, das aus einem anderen Wort durch Umstellung (Permutation) der einzelnen Buchstaben oder Silben gebildet wurde.


Anagramm ? Wikipedia

ist das dein Ziel? dann musst du aber ganz anders vorgehen,

falls es um Palindrom geht: aaa355bbb ist kein Palindrom von bbbaaa553
bzw. auch wieder Quatsch, ein Palindrom ist ja ein einzelnes Wort 
was ist überhaupt dein Ziel, ich schaue nochmal ins erste Post


----------



## SlaterB (16. Feb 2012)

so, also dein Beispiel mit true ist dann korrekt,
das ist aber nur zufällig, weil der letzte Vergleich (b und b) passt,


istAnagramm("aaa35bbb5", "bbbaaa553")
liefert false, obwohl es genauso klappen sollte, weil zuletzt b und 5 verglichen werden


du könntest z.B. in beiden Strings die einzelnen Zeichen sortieren, dann muss am Ende 2x der gleiche String rauskommen


----------



## iks (16. Feb 2012)

Hmm, also Anagramm bedeutet doch, das zwei Woerter, sagen wir Strings in unserm Fall, die gleichen buchstaben in gleicher anzahl beeinhalten. Sollte es das nicht bedeuten, ist es dennoch das, was ich abfragen moechte.

Daher war meine idee:

Ich nehme mir den ersten Buchstaben des ersten Strings, und pruefe dann ob es ihn noch ein anderers mal gibt....und ich merke gerade auch hier schon während ich schreibe, das mein Ansatz quatsch ist, weil ich ja auch pruefen muss, wie oft jeder einzelne vorkoemmt, ARG. Also doch der Schlafmangel, letzte Woche hat das alles noch so gut gefunzt mit dem Programmieren

Okay, RÜCKZUG, So kann es natürlich nicht gehen. MEIN FEHLER....***Peinlich***.


----------



## Gossi (16. Feb 2012)

Wenn Groß- und Kleinschreibung egal sind mal nen kleiner Denkanstoß:
------------------------------------------------
String nr1 = eingangsStringNr1.inKleinbuchstaben;
String nr2 = eingangsStringNr2.inKleinbuchstaben;

int inNr1 = 0;
int inNr2 = 0;

für jeden char zwischen 97 und 122

für jeden char in nr1
ist aktueller char der gleiche: inNr1++;

für jeden char in nr2
ist aktuellers char der gleiche: inNr2++;

stimmt inNr1 mit inNr2 überein?
------------------------------------------------
Keine gute Lösung, aber wenigstens etwas ^^


----------



## iks (16. Feb 2012)

Hmmja, also ich habe auch einen neuen Ansatz:

Ich zaehle jeweils alle vorkommenden zeichen einzeln durch, das ergebnis speicher ich in jeweils einem Array, alphabetisch.
Zum schluss vergleiche ich dann nur noch die Arrays, die die Ergebnisse der Buchstabenzaehlung enthalten, das muesste funktionieren.
Aber ich glaub vorher mach ich nochmal n kleines nickerchen damit ich nich wieder solche peinlichen Fragen stelle


----------



## iks (16. Feb 2012)

Um meine Ehre wenigstens ein bischen zu retten, hier mein Code, und der funtkioniert auch glatt. Einziges problem ist, das ich es diesmal gar nicht über Boolean variablen abfrage , also auch kein return ergebnisboolean am Ende. Aber prinzipiell läufts so.
Zumindest für Strings die aus kleinbuchstaben bestehen, ansonsten muesste ich sie konvertieren. Und buchstaben aus dem Alphabet sollten es auch sein...okayokay  schon wieder merke ich beim schreiben, dass da noch einiges zu verbessern ist, aber unter diesen (meinen)bestimmten vorgaben läuft es so ganz gut:


```
public static void istAnagramm(String s1, String s2) {
		
		int ergebnis = 0;
		
		char []zeichenArray = {'a', 'b', 'c' ,'d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
		if (s1.length() != s2.length()) {
			ergebnis++;			
		} // Ende if
		
		int[] s1result = new int[zeichenArray.length];
		int[] s2result = new int[zeichenArray.length];
		
		char s1vokal, s2vokal;		
		
		
		for(int j =0; j < zeichenArray.length; j++) {
			
			for(int i = 0;i < s1.length();i++) {
		
				s1vokal = s1.charAt(i);
			
				if(s1vokal == zeichenArray[j]) {
					s1result[j]++;					
				} //end if	
			} // end for		
		} // end for
		

		for(int j =0; j < zeichenArray.length; j++) {
			
			for(int i = 0;i < s2.length();i++) {
		
				s2vokal = s2.charAt(i);
			
				if(s2vokal == zeichenArray[j]) {
					s2result[j]++;					
				} //end if	
			} // end for		
		} // end for

		for (int k = 0; k < s1result.length; k++) {
			
			if(s1result[k] > s2result[k] || s1result[k] < s2result[k]) {
				ergebnis++;
			} // end if
									
		} // end for
					
		if (ergebnis > 0) {
			System.out.println("false");
			
		} // end if
		else System.out.println("true");
						
	} // end istAnagramm()
```


----------



## SlaterB (16. Feb 2012)

für > oder < gibt es auch !=

und nimm lieber ein großes Array von 0-200 oder gar bis 70.000,
und nimm jeden char direkt als Array-Index,
das spart dir die innere Schleife, die äußere über den String:

```
for (einmal über den String) {
s1result[s1.charAt(i)]++;     
}
```


----------

