Moin,
habe eine Aufgabe bekommen die lautet wie folgt:
Aufgabe 4: Anagramme (4 Punkte) Ein Anagramm einer Zeichenkette ist eine Zeichenkette mit exakt gleich vielen, identischen Zeichen in gegebenenfalls anderer Reihenfolge. Beispiel: betrug und geburt sind Anagramme voneinander. Außerdem sollen Leerzeichen ignoriert werden, so dass auch tom marvolo riddle und i am lord voldemort Anagramme voneinander sind. Klein-/Großschreibung soll hingegen berücksichtigt werden. Schreiben Sie eine Methode public static boolean anagramm(String s1, String s2), die prüft, ob die beiden Argumente Anagramme voneinander sind. Testen Sie in der main! Gehen Sie dabei wie folgt vor (und nicht anders, etwa Sortieren mit eingebauten Methoden): Entfernen Sie zunächst alle Leerzeichen (Aufgabe 3). Entfernen Sie nacheinander jedes Zeichen in s1 aus s2, falls s1 und s2 dieselbe Länge haben.
ich habe das Programm soweit bekommen, dass es Groß- und Kleinschreibung ignoriert leider hänge ich bei dem Punkt mit dem Leerzeichen löschen und das hat mir den Code auch total zerschossen...
Java:
publicclassPalindrom{staticint counter;publicstaticvoidmain(String[] args){System.out.println(anagramm("tommarvoloriddle","iamlordvoldemort"));publicstaticbooleananagramm(String s1,String s2){String a = s1.replaceAll(" ","");String b = s2.replaceAll(" ","");
a=s1.toLowerCase().trim();
b=s2.toLowerCase().trim();if( a.length()== b.length()){for(int i =0; i < a.length(); i++){for(int j =0; j < b.length(); j++){if(a.charAt(i)== b.charAt(j)){
counter++;}}}}if( counter == a.length()){returntrue;}else{returnfalse;}}
P.s deswegen sieht der code jetzt auch ein bisschen komisch aus, da ich sehr viel rumprobiert habe.
Das musst Du also schon eine Aufgabe zuvor gemacht haben, oder?
Wenn Du das mit replaceAll machen willst, hast Du es im Code oben schon richtig gemacht (man könnte statt " " auch "\\s" verwenden, um sämtliche Whitespace-Character zu ersetzen). Was natürlich keinen Sinn gibt, ist erst der Variablen a den String s1 ohne Leerzeichen zuzuweisen und anschließend den Wert der Variablen a mit dem String s1 in Kleinbuchstaben zu überschreiben.
Was natürlich keinen Sinn gibt, ist erst der Variablen a den String s1 ohne Leerzeichen zuzuweisen und anschließend den Wert der Variablen a mit dem String s1 in Kleinbuchstaben zu überschreiben.
Gehen Sie dabei wie folgt vor (und nicht anders, etwa Sortieren mit eingebauten Methoden):
- Entfernen Sie zunächst alle Leerzeichen (Aufgabe 3).
- Entfernen Sie nacheinander jedes Zeichen in s1 aus s2, falls s1 und s2 dieselbe Länge haben.
Also das mit den Leerzeichen hast Du schon einmal hinbekommen. Kannst du den zweiten Punkt etwas ausführlicher umschreiben?
Und ich sehe bei Dir kein Entfernen sondern nur irgendwas mit zählen - also würde ich den Teil deines Codes ggf. komplett verwerfen und mir erst einmal überlegen, was man denn machen kann um das mit dem Anagramm über Entfernen von Zeichen zu ermitteln.
Wenn Du Code postest, dann bitte in Code-Tags (die drei Punkte neben dem Smiley, dann auf Code, dort Java einstellen, Code inkl. Einrückungen in das Textfeld kopieren).
Hier erstmal der relevante Code nochmal formatiert. Die Rückgabe habe ich schon mal abgekürzt - Sinn ergibt sie aber keinen, denn warum sollte counter so lang wie s1 werden?
Java:
publicstaticbooleananagramm(String s1,String s2){String a = s1.replaceAll(" ","");String b = s2.replaceAll(" ","");if( a.length()== b.length()){for(int i =0; i < a.length(); i++){for(int j =0; j < b.length(); j++){if(a.charAt(i)== b.charAt(j)){
counter++;}}}}return counter == s1.length();}
EDIT: und halte Dich an das, was @JustNobody Dir vorgeschlagen hat
Das ganze war so gedacht: Die Anagramme müssen ja gleich lang sein. Deswegen habe ich einen counter eingerichtet der solange hochzählt bis es der String länge entspricht und wenn die Strings noch die gleichen Chars enthalten soll true ausgegeben werde (wegen boolean)
Also dazu zwei Punkte:
a) Der Lösungsweg ist vorgegeben. Eigene Lösungswege sind daher nicht zielführend.
b) Deine Idee dürfte nicht funktionieren. Denn wenn ich es richtig sehe und der erste String "ab" ist, dann zählt er bei "aa" bis 2, was der Länge des strings entspricht. Und bei "aab" und "aab" zählt er bis 5 was nicht der Länge entspricht ....
Also müsste ich erstmal alle leerzeichen entfernen das habe ich verstanden. Aber wie ist das gemeint, mit dem es sollen nach und nach alle zeichen aus s1&s2 entfernt werden.
Bitte fange erst dann mit Code und so an, wenn Du genau verstanden hast, wie die Erkennung eines Anagrammes mit "entfernen des ersten Buchstabens aus beiden Strings" funktionieren kann!
Und wie mihe7 angedeutet hat, ist die Aussage zu Anagramm noch nicht vollständig (oder Du meinst das Richtige, aber die Aussage war noch missverständlich).
"aaab" und "bbbba" haben die gleiche Länge und die gleiche Anzahl an Buchstaben ... aber um das abzukürzen:
Anagramm bezeichnet eine Buchstabenfolge, die aus einer anderen Buchstabenfolge allein durch Umstellung (Permutation) der Buchstaben gebildet ist.
Also jeder Buchstabe muss in genau der gleichen Anzahl in beiden Zeichenketten vorkommen.
Wie kannst Du mit Stift und Zettel prüfen, ob zwei Zeichenketten ein Anagramm bilden - und dabei nutzt Du das Streichen des ersten Buchstabens in beiden Zeichenketten und die verbliebene Länge der Zeichenketten ...
Also was machst Du mit Stift und Zettel, wenn Du "abcabcabc" und "cabcabcab" gegeben hast?
Vermutlich nur beim Tippen das "gleich" vergessen:
Ja, wenn ein Buchstabe aus beiden Zeichenketten gestrichen wird, dann müssen beide Zeichenketten danach wieder gleich lang sein.
Aber was bedeutet das im Detail?
Bei meinem Beispiel: Du streichst erst alle a, dann alle b und dann alle c - und danach müssen dann beide Zeichenketten leer sein? Oder reicht das nicht?
Ich habe es jetzt auf einem Blatt Papier gemacht und wenn ich danach gehen würde, wären beide Ketten leer aber aufgrund der Art wie du die Frage gestellt hast denke ich, dass das ganze einen Twist hat den ich nicht sehe...
Also im Grunde wollt ihr mich auf den Trichter bringen, das meine Methode jedes char überprüft, dieses dann, falls vorhanden, in beiden Ketten entfernt bis das ganze Null ist. Und natürlich nach jedem Schritt testet ob beide Strings noch die gleiche länge haben? Fühle mich gerade richtig dumm, weil ihr euch so mühe gebt und ich es nicht schnalle lol
Ich verstehe jetzt wie es gemeint ist, aber leider nicht wie ich das Streichen programmieren könnte. Habe auch schon in der Dokumentation für Strings geguckt welche mich aber nur noch mehr verwirrt hat
Also im Grunde wollt ihr mich auf den Trichter bringen, das meine Methode jedes char überprüft, dieses dann, falls vorhanden, in beiden Ketten entfernt bis das ganze Null ist. Und natürlich nach jedem Schritt testet ob beide Strings noch die gleiche länge haben? Fühle mich gerade richtig dumm, weil ihr euch so mühe gebt und ich es nicht schnalle lol
Jetzt scheinst Du es doch zu haben. Ich unterstreiche noch einmal zwei Punkte:
a) Nach jedem Entfernen musst du die Länge der Zeichenketten prüfen.
b) am Ende ist die erste Zeichenkette leer (und die zweite auch, so es Anagramme waren)
Das Entfernen hast Du ja schon für Leerzeichen gemacht. Also könntest Du prinzipiell das replaceAll nutzen. Hier ist die Anmerkung wichtig, dass dies nicht für alle Zeichen funktionieren wird, da ein regulärer Ausdruck erwartet wird und ein paar Zeichen haben eine besondere Bedeutung (z.B. der '.' steht für ein beliebiges Zeichen).
Somit können wir nun eine Schleife mit Abbruchbedingungen definieren. Wann gehen wir nicht in die Schleife, die den ersten Buchstaben aus der ersten Zeichenkette nimmt und aus beiden Zeichenketten entfernt? Was muss da gegeben sein?
Und was die Lösung von @abc66 angeht: Die ignorierst Du bitte einfach - er hat die gestellte Aufgabe nicht korrekt gelesen und bietet daher eine Lösung an, die eben auch nicht den Vorgaben entspricht. (Davon abgesehen ist es schlicht kontraproduktiv für Dein Verständnis, denn Du bist dicht dran es selbst gelöst zu haben. Es hat schon einen Grund, warum wir Dir nicht einfach eine fertige Lösung hinklatschen....)
Das wäre ja auch nicht Sinn der Sache. Ich muss ja auch verstehen + anwenden können. Kann euch ja auch nicht in meiner Klausur fragen. Oder vielleicht doch?
... finde einen char der in beiden Vorhanden ist
lösche diesen
vergleiche ob s1 == s2
suche gleichen char--> entfernen--> vergleichen until s1 && s2 == 0
so grob oder
wäre das denn jetzt der Richtige weg? Bevor ich mich jetzt hier wieder fest fahre
Nachtrag: Oder muss ich noch eine zweite for schleife anlegen die s2 durchgefht?
So lange Du keine Lösungsidee in algorithmischer Weise beschreiben kannst, macht es keinen Sinn irgendwas herum zu programmieren. Der Lösungsansatz muss in erster Linie mal so genau sein, dass er nachvollziehbar ist - er muss sich noch nicht 1:1 in Methodenaufrufe übersetzen lassen.
1. Testen ob s1==s2
2. prüfen ob s1.charAt(0) in s2 vorhanden ist
3. falls true soll s1.charAt(0) aus s2 aus s1 und s2 entfernt werden
4. Wieder Testen ob s1==s2
5. wieder schritt 2 nur mit s1.charAt(1) bis s1,length && s2.length == 0 ist
Und was die Lösung von @abc66 angeht: Die ignorierst Du bitte einfach - er hat die gestellte Aufgabe nicht korrekt gelesen und bietet daher eine Lösung an, die eben auch nicht den Vorgaben entspricht. (Davon abgesehen ist es schlicht kontraproduktiv für Dein Verständnis, denn Du bist dicht dran es selbst gelöst zu haben. Es hat schon einen Grund, warum wir Dir nicht einfach eine fertige Lösung hinklatschen...
Oh, ich sehe gerade, mein Ansatz, alle umgekehrten Zeichen zu entfernen, ist in Bezug auf die Aufgabenstellung und allgemein zu kompliziert... Sorry for that.
Wiederhole so lange s1 und s2 gleich lang und nicht leer sind {
c := erstes Zeichen aus s1
entferne alle Vorkommen von c aus s1 und s2
}
Gib zurück ob s1 und s2 leer sind.