Zeichen in String vergleichen

regtan

Aktives Mitglied
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;
   }
 
Das Erste was mir so auffällt ist, dass du bei i=1 beginnst, der erste Character in einem String sich aber an der Position 0 befindet.
 
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.
 
Was hab ich falsch in mein Code?
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;
 
wie kann ich das anders schreiben weil != geht bei char nicht
warum sollte das nicht gehen ???

EDIT:
Java:
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" );
      }
liefert immer schön brav "Ungleichheit" 🙂
 
Ich dachte das nur beim logischen Operationen und nicht beim char geht. Ich hab es anders probiert aber bei "abbccc" kommt komischerweise false.
Code:
         if (a != b) {
           return false;
         }
 
Diese Vergleiche gehen mit allen primitiven Datentypen (aber bspw. eben nicht mit 'String', das 'String' KEIN primitiver Datentyp ist) !!

Dir wurde weiter oben schon geschrieben, dass Dein Code wenig mit dem Problem zu tun hat!

Wie schaut Dein aktueller Code denn nun aus??
Mit welchen konkreten String testet Du??
Was kommt raus??

Fragen über Fragen ... 🙄
 
Code:
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 ....

Was hast Du denn genau erwartet ??
Lies Dir vielleicht mal dies hier durch:
http://www.java-forum.org/forum-faq-beitraege/7407-man-fragen-richtig-stellt.html

Gruß Klaus
 
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.
 
Vielleicht postest Du mal erst die Aufgabenstellung ...
Eine richtige Logik habe in der Methode eh' noch nicht entdecken können!

Du gibst einen beliebigen String rein ... was soll wann als Ergebnis dabei heraus kommen ??
Was genau ist der Sinn der inneren for-Schleife??
 
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.
 
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.
 
Java:
      h+= i+1;
      k+= i+2;
ich verstehe nicht wieso sollte bis- und von- wert mit 1 erhöht??
ich glaube da beim
Code:
for (int j = h; j <= k ; j++) {
         char a = s.charAt(j);
         char b = s.charAt(j+1);
hast du recht das beim j+1 den Intervall überschreitet. Irgendeine Idee was könnte man ändern?
 
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.
 
Ja stimmt da kommt ein "out of range" Fehler aber ich verstehe nicht was ich ändern soll. Da j<k ist, wieso geht das noch weiter?
 
Da j<k ist, wieso geht das noch weiter?
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;
   }
 
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;
 
Was soll das "if (l != z ){ " bewirken? So wie es jetzt ist wird hier false returned da sich das "z" erhöht, das "l" aber gleichbleibt.
 
Das hat aber auch nichts geändert wenn ich innerhalb der Schleife gestellt habe. Es Sollte irgendwo anders das Problem liegen (glaub ich).
 
Wie wär's mit ner pragmatischeren Lösung?

EIne Methode:

Java:
boolean strHasSameChars(String toCheck){
      //return ob alle chars in dem String gleich sind
}

und eine zweite Methode

Java:
boolean hasFormat(String str){
        int numIntervals = Math.floor(Math.sqrt(str.length()/2));
        if((numIntervals * (numIntervals+1))/2 != str.length()){
                return false;
        }
        for(int i = 0; i < numIntervals; i++){
                int start = ((i-1)*i)/2;
                if(!strHasSameChars(str.substring(start, start+i)){
                          return false;
                }
        }
        return true;
}


Sollte eigentlich funktionieren, bis auf dass der Code auch bei "aaa" true zurück gibt
 
Sry, es muss vermutlich heissen
Java:
int start = ((i+1)*i)/2;

und
Java:
str.substring(start, start+i+1)
 
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;
}
 
Etwas licht in 's Dunkle:
Java:
    public static void main(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....
 

Neue Themen


Zurück
Oben