Hallo! Ich versuch die Zeichen in eine String zu vergleichen und zu überprüfen ob der String so aussieht (abbcccdddd....). Was hab ich falsch in mein Code?
Code:
boolean wort(String s) {
for (int i = 1; i < s.length()-1; i++) {
for (int j = 1; j < i ; j++) {
char a = s.charAt(i);
char b = s.charAt(i+1);
if (a == b) {
return true;
}
}
}return false;
}
Du vergleichst auch "b" mit "b" (was gleich ist) und gibst true zurück.
Durch das "return" wird die Methode verlassen (sprich die restlichen Buchstaben werden nicht mehr verglichen.
Der Code hat praktisch nichts mit dem Problem zu tun. Warum sollte der String denn dem gewünschten Format entsprechen, nur weil einmal a==b erfüllt ist?
Ich würde das schrittweise angehen und mich erstmal damit beschäftigen, welche Positionen eigentlich gleich sein müssen, z.B Position 3 bis 5 für Block c. Dann würde ich ein Programm schreiben, dass einfach nur die Anfangspositionen der Blöcke ausgibt. Sobald du das geschafft hast, bist du schon ein ganzes Stück weiter.
Theoretisch sollte es so funktionieren, außer "if" teil.
Code:
int h = 1;
int k = 2;
for (int i = 1; i <= s.length()-1; i++) {
for (int j = h; j <= k ; j++) {
char a = s.charAt(j);
char b = s.charAt(j+1);
if (a == b) { //wie kann ich das anders schreiben weil != geht bei char nicht
return true;
}
}
h+= i+1;
k+= i+2;
}return false;
String myString ="1234567890";char a = myString.charAt(2);char b = myString.charAt(7);if( a == b ){System.out.println("Gleichheit");}if( a != b ){System.out.println("Ungleichheit");}
boolean wort(String s) {
int h = 1;
int k = 2;
for (int i = 1; i <= s.length()-1; i++) {
for (int j = h; j <= k ; j++) {
char a = s.charAt(j);
char b = s.charAt(j+1);
if (a != b) {
return false;
}
}
h+= i+1;
k+= i+2;
}return true;
jetzt mal lax angenommen, dass Du weiterhin mit "abbcccdddd" testet, so wie anfangs geschrieben und mal davon abgesehen, dass Du immer noch nicht die richtigen Indices nimmst (so wie es dir gleich in der ersten Antwort genannt wurde) sollte es genau DAS machen, was Du programmiert hast:
sobald Du auf die ersten beiden ungleichen Zeichen triffst, wird die Methode mit 'false' beendet ....
Also, ich hab auch oben erklärt warum i mit 1 anfängt und nicht mit 0 und trotzdem hab ich auch mit 0 probiert und es macht kein unterschied. Natürlich sollte false kommen wenn 2 ungleiche Zeichen beim interval h-k sind. Aber beim mir kam false wenn die trotzdem gleich sind. Das ist das Problem.
Aufgabe: Implementieren Sie die Methode boolean wort(String s) (Java). Diese soll überprüfen, ob der in s übergebene String ein "Schnapswort" ist, bei dem der n-te Buchstabe jeweils auch n mal hintereinander auftritt. Beispiele: "1223334444", "ABBCCCDDDDEEEEE"
Der innere for schleife sollte die Zeichen untersuchen die von stelle 1-2, 3-5,6-9 usw. ob gleich sind.
Er soll glaube ich prüfen, ob es ein String dieser Art ist "abbccc" oder "abb" oder "abbcccdddd" -> true, "abbbbcc" -> false. So habe ich es verstanden ? Sowas gabs ja hier letztens auch schon, soweit ich mich erinnere.
Du vergleichst die falschen Intervalle und du vergleichst die Intervalle falsch.
Daran:
Java:
h+= i+1;
k+= i+2;
sieht man doch, dass der Bis-Wert immer um genau eins größer ist, als der Von-Wert. Das kann doch nicht stimmen.
Beim letzten Schleifendurchlauf ist j=k, du vergleichst also Position k mit Position k+1, die bereits zum nächsten Intervall gehört. Das kann also auch nicht stimmen:
Java:
for(int j = h; j <= k ; j++){char a = s.charAt(j);char b = s.charAt(j+1);
Du solltest Schreibtischtests machen, um zu verstehen, was dein Code tut.
Ich finde die Aufgabenstellung auch nicht ganz klar, weil man nicht wirklich weiß, ob beispielsweise xxxyyyzzzz dem gewünschten Format entspricht. Ich gehe im Moment davon aus, dass da true zurück geliefert werden soll.
Du könntest die Abbruchbedingung auf j<kändern. Du wirst dann wohl noch auf weitere Probleme laufen, aber grundsätzlich bist du inzwischen ziemlich dicht dran.
Wahrscheinlich versuchst du, auf eine Stringposition zuzugreifen, die hinter dem Stringende liegt. Deine äußere Schleife läuft ja von der zweiten bis zur letzten Position. Bei "abbccc" wären das also 5 Iterationen. Inzwischen arbeitest du in einer Iteration der äußeren Schleife aber nicht nur ein Zeichen ab, sondern ein ganzes Intervall, so dass du im Beispiel bereits nach zwei Iterationen fertig bist. Bei der dritten Iteration kommt es folglich zu einem "out of range"-Fehler.
Bleiben wir beim Beispiel "abbccc" und betrachten den Zeitpunkt, dass die äußere Schleife für i=2 fast abgeschossen ist. Dann wird h auf 6 gesetzt (3+i+1) und k auf 9 (5+i+2). Dann beginnt die nächste Iteration der äußeren Schleife also mit i=3, h=6 und k=9. In der inneren Schleife wird zwar sicher gestellt, dass j < k ist, aber k kann eben deutlich größer als die höchste Stringposition (hier 5) sein.
Die schnellste, aber schmutzige Lösung wäre wahrscheinlich, heraus zu springen, sobald j groß genug ist. Sauberer wäre es, als äußere Schleife keine for-Schleife zu verwenden. Bei einer for-Schleife sollte die Anzahl der Iterationen von Beginn an bekannt sein, sonst wird es häßlich.
Mit der äußeren Schleife würde ich jeweils zu Anfang die Anzahl der erwarteten gleichen Buchstaben um 1 erhöhen. (Im ersten Durchgang 1, dann 2, dann 3 usw)
Mit der inneren Schleife würde ich die Anzahl der gleichbleibenden Buchstaben (ab dem aktuellen Index) zählen und dann mit der erwarteten Anzahl vergleichen. Ist das nicht der Fall --> return false. (Der erste aktuelle Index beginnt natürlich mit 0)
Stimmt die Anzahl dann den Index für den nächsten Durchgang um genau diese Anzahl erhöhen.
Die schnellste, aber schmutzige Lösung wäre wahrscheinlich, heraus zu springen, sobald j groß genug ist. Sauberer wäre es, als äußere Schleife keine for-Schleife zu verwenden. Bei einer for-Schleife sollte die Anzahl der Iterationen von Beginn an bekannt sein, sonst wird es häßlich.
Das problem ist jetzt wenn string kürzer ist als es sein muss. z.B. "abbcc"
Code:
int h = 1;
int k = 2;
int i = 0;
for (int j = h; j < k; j++) {
if (k<= s.length()){
char a = s.charAt(j);
char b = s.charAt(j+1);
i++;
if (a != b) {
return false;
}
}
}
h+= i+1;
k+= i+2;
return true;
}
Du berechnest die Grenzen für das nächste Intervall auch noch korrekt (3 bis 5). Aber du überprüfst es nicht. Deine Schleife wird nur einmal durchlaufen.
Ja stimmt ich hab irgendwie umgeschrieben aber immer noch ohne Erfolg
Code:
int h = 1;
int k = 2;
int l = k-h;
int z = 1;
for (int i = 1; i<=s.length();i++){
for (int j = h; j < k; j++) {
if (l != z ){
return false;
}
char a = s.charAt(j);
char b = s.charAt(j+1);
z++;
if (a != b) {
return false;
}
}
h+= i+1;
k+= i+2;
}return true;
So bekommt man zumindest schonmal den OutOfBounds Fehler weg. Aber korrekt ist es immer noch nicht...
Code:
public boolean wort(String s)
{
int h = 1;
int k = 2;
for(int i = 1; i <= s.length(); i++)
{
for(int j = h; j < k && j+1 < s.length(); j++)
{
char a = s.charAt(j);
char b = s.charAt(j+1);
if(a != b)
{
return false;
}
}
h += i+1;
k += i+2;
}
return true;
}
Ich würde den Algo so implementieren wie ich es in meinem ersten Kommentar beschrieben habe. Indeces zum Starten bestimmen, gleiche Buchstaben zählen und vergleichen ob Anzahl mit der erwarteten übereinstimmt. usw.
Beim testen kommt sowas raus:
* Bestanden: Die Methode erkennt, dass es sich beim übergebenen Wort um ein Schnapswort handelt
* Fehlgeschlagen: Die Methode erkennt, dass für ein Schnapswort ein Zeichen am Ende fehlt
Variablenwert nicht wie erwartet, nachdem folgender Code ausgeführt wurde:
Wert der Variable "result" nach der Ausführung des folgenden Codes:
boolean result = BoozeWord.[contains, Contains]("abbcc");
result erwartet: false
tatsächlich: true
Ich sag ja. Immer noch nicht wie gewünscht. Es wird zb auch nicht erkannt wenn hinten "eins zuviel" ist... Auf die schnelle kriege diesen Algo nicht hin (immer zwei nachfolgende Elemente miteinander vergleichen).
Hier mal meine Variant eines Algos (Zählen von gleichen Elementen und anschließenden Vergleich mit erwarteten Werten):
Code:
public boolean wort(String s)
{
int mark = 0;
for(int i = 0; i < s.length(); i += mark)
{
mark++;
char checkFor = s.charAt(i);
int occurrences = 0;
for(int j = 0; i+j < s.length(); j++)
{
if(checkFor == s.charAt(i+j))
occurrences++;
else
break;
}
if(occurrences != mark)
return false;
}
return true;
}
publicstaticvoidmain(String[] args){String text ="abbcccddddeeeee";for(int i =0; i *(i +1)/2< text.length(); i++){String sub = text.substring(i *(i +1)/2, i *(i +1)/2+ i +1);System.out.println("sub = "+ sub);char[] arr = sub.toCharArray();Arrays.sort(arr);if(arr[0]!= arr[arr.length -1]){System.out.println("Falsch");return;}}System.out.println("Richtig");}
Der kleine Gauß hilft dabei. Das Sortieren ist vielleicht etwas On-top, aber ich hab an (n^2) vermeiden gedacht...
Edit: Merke gerade, es ginge vielleicht viel einfacher....