# Zeichen in String vergleichen



## regtan (26. Jul 2016)

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?

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


----------



## kiwara (26. Jul 2016)

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.


----------



## regtan (26. Jul 2016)

Ja aber der erste Zeichen ist nicht mit dem nächsten gleich, sonder ab 2 Zeichen schon.


----------



## VfL_Freak (26. Jul 2016)

regtan hat gesagt.:


> a aber der erste Zeichen ist nicht mit dem nächsten gleich, sonder ab 2 Zeichen schon.


ääh ... was ??? 

beschreib doch erst, was nicht so funktioniert wie erwartet, rsp. welche Fehler kommen!

Im übrigen hat @kiwara natürlich Recht!!
Beispiel: ein String mit 10 Zeichen Inhalt hat die Indices 0 .. 9 !!

Gruß Klaus


----------



## regtan (26. Jul 2016)

Na ja beim diese string ("abbcc") kommt raus true obwohl false kommen sollte.


----------



## Joose (26. Jul 2016)

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.


----------



## Meniskusschaden (26. Jul 2016)

regtan hat gesagt.:


> 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.


----------



## regtan (26. Jul 2016)

Theoretisch sollte es so funktionieren, außer "if" teil.

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


----------



## VfL_Freak (26. Jul 2016)

regtan hat gesagt.:


> wie kann ich das anders schreiben weil != geht bei char nicht


warum sollte das nicht gehen ???

*EDIT:*

```
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"


----------



## regtan (26. Jul 2016)

Ich dachte das nur beim logischen Operationen und nicht beim char geht. Ich hab es anders probiert aber bei "abbccc" kommt komischerweise false. 

```
if (a != b) {
           return false;
         }
```


----------



## VfL_Freak (26. Jul 2016)

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 ...


----------



## regtan (26. Jul 2016)

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


----------



## VfL_Freak (26. Jul 2016)

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


----------



## regtan (26. Jul 2016)

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.


----------



## VfL_Freak (26. Jul 2016)

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??


----------



## regtan (26. Jul 2016)

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.


----------



## Cromewell (26. Jul 2016)

VfL_Freak hat gesagt.:


> Du gibst einen beliebigen String rein ... _*was*_ soll _*wann *_als Ergebnis dabei heraus kommen ??


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.


----------



## Meniskusschaden (26. Jul 2016)

Du vergleichst die falschen Intervalle und du vergleichst die Intervalle falsch.
Daran:

```
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:

```
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.


----------



## Meniskusschaden (26. Jul 2016)

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.


----------



## Flown (26. Jul 2016)

Nur für mein Verständnis: Dein Code versucht zu prüfen ob 1xa, 2xb, 3xc, 4xd, 5xe, .... vorkommt und so weiter?


----------



## VfL_Freak (26. Jul 2016)

Flown hat gesagt.:


> Nur für mein Verständnis: Dein Code versucht zu prüfen ob 1xa, 2xb, 3xc, 4xd, 5xe, .... vorkommt und so weiter?


So scheint es zu sein ... ich bin auch von was ganz anderem ausgegangen


----------



## regtan (26. Jul 2016)

```
h+= i+1;
      k+= i+2;
```
ich verstehe nicht wieso sollte bis- und von- wert mit 1 erhöht??
ich glaube da beim

```
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?


----------



## Meniskusschaden (26. Jul 2016)

regtan hat gesagt.:


> ich verstehe nicht wieso sollte bis- und von- wert mit 1 erhöht??


Du hast recht, da habe ich nicht richtig hingesehen. Sorry.


----------



## Meniskusschaden (26. Jul 2016)

regtan hat gesagt.:


> hast du recht das beim j+1 den Intervall überschreitet. Irgendeine Idee was könnte man ändern?


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.


----------



## regtan (26. Jul 2016)

Ja hab ich geändert aber trotzdem geht nicht  ich verstehe nicht warum


----------



## Meniskusschaden (26. Jul 2016)

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.


----------



## regtan (26. Jul 2016)

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?


----------



## Meniskusschaden (26. Jul 2016)

regtan hat gesagt.:


> 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.


----------



## X5-599 (26. Jul 2016)

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.


----------



## regtan (26. Jul 2016)

Meniskusschaden hat gesagt.:


> 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"

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


----------



## Meniskusschaden (26. Jul 2016)

Den Lösungsansatz verstehe ich nicht. Jetzt prüfst du doch nur noch das Intervall 1 bis 2, oder übersehe ich da etwas?


----------



## regtan (26. Jul 2016)

Nein wieso 1 bis 2?  Da ist i++ und wird weiter erhöht.


----------



## Meniskusschaden (26. Jul 2016)

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.


----------



## regtan (26. Jul 2016)

Ja stimmt  ich hab irgendwie umgeschrieben aber immer noch ohne Erfolg 

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


----------



## X5-599 (26. Jul 2016)

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.


----------



## regtan (26. Jul 2016)

```
int l = k-h;
```
l sollte nicht gleich bleiben weil auch k und h werden ändern.


----------



## X5-599 (26. Jul 2016)

int l = k-h;

Das steht doch außerhalb der Schleifen. Somit ändert es sich nicht.


----------



## regtan (26. Jul 2016)

Das hat aber auch nichts geändert wenn ich innerhalb der Schleife gestellt habe. Es Sollte irgendwo anders das Problem liegen (glaub ich).


----------



## BuddaKaeks (26. Jul 2016)

Wie wär's mit ner pragmatischeren Lösung?

EIne Methode:


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

und eine zweite Methode


```
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


----------



## BuddaKaeks (26. Jul 2016)

Sry, es muss vermutlich heissen

```
int start = ((i+1)*i)/2;
```

und

```
str.substring(start, start+i+1)
```


----------



## regtan (26. Jul 2016)

was??????


----------



## BuddaKaeks (26. Jul 2016)

Nur ein bisschen rumgespiele mit der Tatsache, dass

```
Summe von 1 bis n = n * (n+1) / 2
```


----------



## X5-599 (26. Jul 2016)

So bekommt man zumindest schonmal den OutOfBounds Fehler weg. Aber korrekt ist es immer noch nicht...


```
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.


----------



## regtan (26. Jul 2016)

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


----------



## BuddaKaeks (26. Jul 2016)

Was hast du getestet? was waren die EIngaben? Welche der 23.000 oben hingeschriebenen Methoden wurde getestet?


----------



## regtan (26. Jul 2016)

@BuddaKaeks
Die Letzt geschriebene von X5-599.


----------



## X5-599 (26. Jul 2016)

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):


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


----------



## BuddaKaeks (26. Jul 2016)

ICh bin immernoch für meine Lösung, die hat nicht so viele for-Schleifen ;D


----------



## Xyz1 (26. Jul 2016)

Etwas licht in 's Dunkle:

```
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....


----------



## BuddaKaeks (26. Jul 2016)

@DerWissende
Lass mal bei text das letzte 'e' weg 
Und guck was passiert...


----------



## regtan (26. Jul 2016)

Danke Leute es hat das von @X5-599 schon geklappt. Ich probiere es noch die andere Methode um mal zu schauen was passiert.


----------



## Xyz1 (26. Jul 2016)

BuddaKaeks hat gesagt.:


> @DerWissende
> Lass mal bei text das letzte 'e' weg
> Und guck was passiert...



Ja,

```
if (text.length() < i * (i + 1) / 2 + i + 1) {
                System.out.println("Falsch");
                return;
            }
```

noch hinzu (direkt nach Anfang der Schleife). Aber irgendwie müsste es doch auch einfacher 'möglich' sein...

Es verwirrt etwas.


----------



## Flown (26. Jul 2016)

Also ich würde auch am Anfang überprüfen, ob die Länge auch stimmt.

```
public static boolean wort(String s) {
  int n = (int) (Math.sqrt(8 * s.length() + 1) - 1) / 2;
  if ((n * n + n) / 2 != s.length()) {
    return false;
  }
  
  for (int i = 0, step = 1; i < s.length(); i += step, step++) {
    char c = s.charAt(i);
    for (int j = 1; j < step; j++) {
      if (c != s.charAt(i + j)) {
        return false;
      }
    }
  }
  return true;
}
```


----------



## Meniskusschaden (26. Jul 2016)

@regtan: Damit das zwischen den verschiedenen Lösungsvorschlägen nicht ganz untergeht: Auch wenn es eleganter geht, ist deine Lösung aus Post #12 im Grunde genommen bereits fertig und ich würde dir dringend empfehlen, die verbliebenen Fehler noch selbst zu beseitigen, auch wenn du jetzt eine andere Lösung hast.
Mir ist in diesem Thread und auch in einigen deiner anderen Threads aufgefallen, dass du meistens nur feststellen kannst, ob das Programm funktioniert oder nicht und dass du Lösungsvorschläge ziemlich unreflektiert einbaust. Du hast offenbar keine richtige Vorstellung, was im einzelnen überhaupt abläuft und wo die Fehlerursache liegen könnte. Wenn ein Programm dann mehrere Fehler enthält (was normal ist), erkennst du es deshalb nicht, wenn du einen Fehler beseitigt hast und dem Ziel einen Schritt näher gekommen bist. In dieser Hinsicht sieht man bei dir kaum Fortschritte. Ich würde deshalb versuchen, Strategien zur Fehlersuche zu entwickeln, etwa durch Schreibtischtests, Ausgabe relevanter Variablen an sinnvollen Stellen und Gebrauch des Debuggers.


----------



## Xyz1 (26. Jul 2016)

Flown hat gesagt.:


> Also ich würde auch am Anfang überprüfen, ob die Länge auch stimmt.



Ich wollte gerade Antworten, dass die Summenformel durch eine 2. Variable zu vermeiden ist, aber du warst schneller...

Ob es übersichtlicher ist... Drei Fragezeichen. : D


----------



## Flown (26. Jul 2016)

DerWissende hat gesagt.:


> Ob es übersichtlicher ist... Drei Fragezeichen. : D


 Wenn man es übersichtlicher gestalten möchte, sollte man auf jedenfall das Überprüfung auf gleiche Zeichen in eine Methode auslagern, wie auch die Berechnungen der Längen am Anfang.


----------



## Xyz1 (26. Jul 2016)

Jetzt mal weg vom Verständnis, was vielleicht noch fehlt: Das riecht schon wieder nach einem (richtigen) Benchmark-Test. : D


----------



## BuddaKaeks (26. Jul 2016)

Zudem fehlt bei euch noch der Test, ob in aufeinanderfolgenden Parts aucg verschiedene chars sind
Nach Aufgabenstellung wäre ja abbccc korrekt aber zB aaaccc falsch, der Algorithmus würde aber true rauskriegen.
Weil Aufgabenstellung war ja:
Schnapszahl <==> der n-te Buchstabe taucht n Mal hintereinander auf.

Is jetzt noch auslegungssache, ob abbaaa erlaub ist, oder ob baab erlaubt ist, immerhin ist b der (im String) erste Buchstabe und kommt auch beim zweiten Vorkommen nur einmal in Folge vor


----------



## X5-599 (27. Jul 2016)

Also ich würde mal behaupten, dass "abbaaa" gültig ist.

Andere Frage: Gehe ich recht in der Annahme, dass die meisten anderen Lösungen, die hier gepostet wurden so funktionieren, dass so oft Buchstaben miteinander verglichen werden wie man erwartet? Also zuerst: 1 innerer Schleifendurchgang (um B und B zu vergleichen), dann 2 innere Schleifendurchgänge (um C und C dann C und C zu vergleichen) usw?
Wenn dem so ist, würde allerdings auch ein String "ABBCCCDDDD DDDDD" als "true" angesehen. Der SPACE dient hier nur der Übersichtlichkeit. Es wird ermittelt, dass B zweimal vorkommt, dass C dreimal vorkommt, dass D viermal vorkommt und dann zum Schluss, dass D fünfmal vorkommt. Wenn ich nur die per Iterationsdurchgang erwarteten Anzahl an gleichen Buschstaben vergleiche, gäbe es hier ein positives Ergebnis. (Jeweils zwei, drei, vier und fünf gleiche Buchstaben hintereinander)
Wie gesagt finde ich, dass Buchstaben schon öfters im String vorkommen dürfen. Aber wenn sie direkt hintereinander auftreten ist das meiner Meinung nach falsch. Es sollten dann festgestellt werden: B kommt zweimal vor, C kommt dreimal vor und D kommt neunmal vor. Ergebnis: Kein Schnappsstring.

Ist natürlich nur meine Auffassung. Was meint ihr?


----------



## BuddaKaeks (27. Jul 2016)

Ja genau das meinte ich ja in meinem Post.
a aabbb wäre true, abb bbb wäre auch true usw.
Aber nach Aufgabenstellung ist das definitv kein Schnapsstring.
Irgend ne Lösung dafür zu finden ist sicher nicht schwer, aber vllt gibt es ja eine ganz elegante Lösung, die irgendwie alles mehr oder weniger gleichzeitig in einer Schleife ohne viel if und else bewerkstelligt?


----------



## X5-599 (27. Jul 2016)

Meine Lösung berücksichtigt sowas. Obs nun elegant ist kann jeder für sich selbst entscheiden


----------



## Flown (27. Jul 2016)

Ein anderer Lösungsansatz wäre erst die Flanken zu erkennen: D.h. sehen an welchen Stellen im Array: `s.charAt(i-1) != s.charAt(i)` liegt.
Danach kann man einfach die Schrittweite jeder Flanke zur Vorhergehenden berechenen und prüfen.

```
public static boolean wort(String s) {
  if (s == null || s.isEmpty()) {
    return false;
  }
  int[] edges = new int[s.length() + 1];
  int length = 0;
  for (int i = 0; i <= s.length(); i++) {
    if (i == 0 || i == s.length() || s.charAt(i) != s.charAt(i - 1)) {
      edges[length++] = i;
    }
  }

  for (int i = 1, step = 1; i < length; i++, step++) { // i == step -> also kann das Eine oder Andere weggelassen werden, aber zwecks Übersichtlichkeit
    int diff = edges[i] - edges[i - 1];
    if (diff != step) {
      return false;
    }
  }
  return true;
}
```


----------



## BuddaKaeks (27. Jul 2016)

Also ich hab noch diese Lösung im Repetoire, sollte eigentlich alle Anforderungen erfüllen:

```
boolean wort(String text){
        char[] chars = text.toCharArray();
        int i = 0, j = 0;
        for(int k = 1; i < chars.length-1; i++){
            if((chars[i] == chars[i+1])^(i == j ? (j+=++k) < 0 : true)){
                return false;
            }
        }
        return i == j;
    }
```


----------



## Xyz1 (27. Jul 2016)

Bitteschön, kann von der Performance glaube ich nicht eingeholt werden:

```
public static void main(String[] args) {
        String text = "abbcccddddeeeeeffffff";
        String text2 = text.toUpperCase();
        System.out.println(schnaps(text));
        System.out.println(schnaps(text2));
    }

    static boolean schnaps(String text) {
        try {
            for (int i = 0, j = 1; i < text.length(); i += j, j++) {
                System.out.println(text.substring(i, i + j)); // just an output ....
                char befor = i > 0 ? text.charAt(i - 1) : (char) (text.charAt(i) - 1);
                char after = text.charAt(i);
                if (befor + 1 != after) {
                    return false;
                }
                for (int k = i; k < i + j; k++) {
                    if (text.charAt(k) != after) {
                        return false;
                    }
                }
            }
        } catch (StringIndexOutOfBoundsException sioobe) {
            return false;
        }
        return true;
    }
```

Auch ich 3 Variablen inzwischen...


----------



## BuddaKaeks (27. Jul 2016)

Wie wärs mit Benchmarktests gegeneinander?


----------



## BuddaKaeks (27. Jul 2016)

Deins sagt falsch für:
String test = "abbeeecccc";


----------



## Xyz1 (27. Jul 2016)

BuddaKaeks hat gesagt.:


> Wie wärs mit Benchmarktests gegeneinander?



Von mir aus, gerne. Aber mein Benchmark Framework spinnt im Moment, also ich kann diesen Test nicht "anfertigen".

Und es geht doch auch darum, regtan muss geholfen werden.^^


----------



## BuddaKaeks (27. Jul 2016)

> Hallo! Ich versuch die Zeichen in eine String zu vergleichen und zu überprüfen ob der String so aussieht (abbcccdddd....).


Ich würde sagen, ihm wurde mehr als genug geholfen


----------



## Xyz1 (27. Jul 2016)

BuddaKaeks hat gesagt.:


> Deins sagt falsch für:
> String test = "abbeeecccc";



Ja, denn:


> , bei dem der n-te Buchstabe jeweils auch n mal hintereinander auftritt.



Der 3-te Buchstabe ist c, tritt aber 0-mal auf.


----------



## BuddaKaeks (27. Jul 2016)

> Der 3-te Buchstabe ist c, tritt aber 0-mal auf.


Das ist jetzt Auslegungssache 
Der dritte Buchstabe im Alphabet oder der dritte im String?


----------



## Xyz1 (27. Jul 2016)

An der Stelle ist die Aufgabenstellung/Definitionem ungenau. 

(Edit: Der Editor und das Thema hakt ganz schön, mittlerweile^^)


----------



## Xyz1 (27. Jul 2016)

Okay, dann Substituiere `+ 1`:

```
public static void main(String[] args) {
        String text = "abbcbcddddeeeeeffffff";
        String text2 = text.toUpperCase();
        System.out.println(schnaps(text));
        System.out.println(schnaps(text2));
    }

    static boolean schnaps(String text) {
        try {
            for (int i = 0, j = 1; i < text.length(); i += j, j++) {
                System.out.println(text.substring(i, i + j)); // just an output ....
                char befor = i > 0 ? text.charAt(i - 1) : (char) (text.charAt(i) - 1);
                char after = text.charAt(i);
                if (befor == after) {
                    return false;
                }
                for (int k = i; k < i + j; k++) {
                    if (text.charAt(k) != after) {
                        return false;
                    }
                }
            }
        } catch (StringIndexOutOfBoundsException sioobe) {
            return false;
        }
        return true;
    }
```


----------



## BuddaKaeks (27. Jul 2016)

Ich glaube, wir führen das ganze am besten hier, und nicht im Anfängerfragenforum weiter:
http://www.java-forum.org/thema/schnapsstring.173997/


----------



## Xyz1 (27. Jul 2016)

Zuvor bleiben aber noch Fragen offen,
1) der n-te Buchstabe des Alphabets oder des Strings,
2) sind Teilstrings auch disjunkte Teilmengen?


----------



## BuddaKaeks (27. Jul 2016)

1) der n-te des Alphabets
2) nö


----------



## Xyz1 (27. Jul 2016)

BuddaKaeks hat gesagt.:


> 2) nö



Doch, sind sie. Aber besser an andere Stelle fortführen.


----------

