1. Zeichenkettenverarbeitung

Im Folgenden wollen wir uns mit Zeichen und Zeichenfolgen beschäftigen und insbesondere mit den Datentypen char, Character, String und StringBuilder.

1.1. String-Objekte

String-Objekte sind in Java allgegenwärtig, sie sind so omnipräsent, dass viele Entwickler sie als eingebaute Datentypen betrachten. Dabei sind Strings nur Objekte, genießen In der Sprache aber Vorzüge. Als Objekte haben sie Methoden, und um diese Eigenschaften handelt der nächste Abschnitt.

1.1.1. Quizz: Ist String ein Schlüsselwort? ☆

Java hat eingebaute Datentypen, darunter int, double, boolean. Ist String ebenfalls ein primitiver eingebauter Datentyp? Ist String ein Schlüsselwort in Java?

1.1.2. Einfache Konkatenation ☆

In HTML werden für Auszeichnungen Tags eingesetzt, ein Beispiel ist <b><i>Bold und Italic</i></b>.

  1. Schreibe eine neue Methode htmlElement(String, String), die ein String mit einem Start- und End-Tag einrahmt. Als Beispiel: htmlElement("b", "Bold ist fett.") liefert "<b>Bold ist fett</b>".

  2. Schreibe eine neue Methode bold(String) und italic(String), die im Hintergrund mit htmlElement(…​) arbeiten.

1.1.3. Alphabet generieren ☆

Methoden können primitive Werte liefern und natürlich auch Objekte. Strings sind Objekte, die man dynamisch aufbauen kann, etwa mit dem Plus-Operator.

Gegeben ist folgende Methode:

static String abcz() {
String s;
s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return s;
}

Sie liefert eine Zeichenkette mit allen Zeichen im Alphabet ("ABCDEF…​Z").

Die Methode ist zwar performant in ihrer Aufgabe, aber nicht sonderlich flexibel, wenn es zum Beispiel darum geht nur gewisse Bereiche zu generieren, etwa von "G" bis "W".

  1. Ändere die Methode, sodass der String dynamisch über eine Schleife generiert wird.

  2. Ergänze eine Methode String abcz(char start, char end).

    • Schreibe eine weitere Methode String abcz(char start, int anz), die ab start dann anz Zeichen liefert. Lässt sich eine der beiden Methoden aufeinander abbilden?

Hinweis: Überlege, wie mit fehlerhaften Parametern umzugehen ist.

1.1.4. Strings füllen ☆

Gesucht ist eine Methode, die einen String aufspreizt, und mit Füllzeichen zwischen den Zeichen mixt. Ein Beispiel von der gewünschten Methode:

  • mix("Die Axt!", "!!")"D!!i!!e!! !!A!!xx!!t!"

1.1.5. Nervös? ☆

Al Dawood kommt zum Großen Don und stottert vor Nervosität.

Schreibe eine Methode boolean isStuttering(String), die prüft, ob jedes Zeichen im String zweimal hintereinander vorkommt.

Beispiel:

  • isStuttering("eehhrrwüürrddiiggeerr ddoon")true

  • isStuttering("dooni deevviitoo")false

1.1.6. Ist das japanisch? ☆

Man sagt Japanern nach, dass sie statt "l" ein "r" sprechen. Das wollen wir ausprobieren, wie sich das "anhört".

  1. Lege eine neue Klasse TalkLikeAJapanese an.

  2. Setze in die Klasse eine neue Klassenmethode void talkJapanese(String s), die einen übergebenen java.lang.String auf dem Bildschirm bringt, aber den Buchstaben "r"/"R" als "l"/"L" ausgibt. Es geht nicht darum einen String zurückzuliefern.

Beispiel: talkJapanese("Riesenrad") ergibt auf dem Bildschirm die Ausgabe Liesenlad.

  • Teste die Methode mit einer main-Methoden.

  • Schreibe nicht nur eine Variante, sondern versuche mindestens zwei Varianten zu programmieren.

1.1.7. Trotziges Verhör ☆

Tony der Trotzige ist für den Schwarzmarkt vom Großen Don zuständig, doch er wird geschnappt und von der Polizei verhört. Um es den Polizisten zu nerven wiederholt er alles was sie sagen und setzt ein "Keine Ahnung!" hinten dran. Fragt der Polizist: "Wo ist das Schwarzmarktlager?", sagt Tony: "Wo ist das Schwarzmarktlager? Ich nix wissen!"

  1. Lege eine neue Klasse an und Frage von der Kommandozeile eine Eingabe ab.

  2. Auf dem Bildschirm gib aus, was von der Eingabe kommt, hänge aber ein " Ich nix wissen!" hinten dran.

  3. Wenn von der Polizei keine Frage gestellt wird — die Eingabe endet nicht mit ? — hält Tony der Trotzige ganz seinen Mund.

  4. Kommt von der Eingab selbst "Keine Ahnung?", und das unabhängig von der Groß-/Kleinschreibung, erwidert Tony trotzig "Genau!".

1.1.8. Quizz: Wie lassen sich zwei Strings in Java vergleichen? ☆

Wie lassen sich Strings in Java vergleichen? Nenne mindestens zwei Möglichkeiten?

1.1.9. Quizz: Ist equals(…​) symmetrisch? ☆

Unter der Annahme, dass s ein String ist, gibt es einen Unterschied zwischen s.equals("tutego") und "tutego".equals(s)?

1.1.10. Camel-Case-Zerleger ☆

In Java ist die übliche Schreibweise für Bezeichner Camel-Case; jedes neue Segment beginn mit einem Großbuchstaben. Beispiele sind: ArrayList, numberOfElements.

Schreibe eine neue Methode camelCaseSplitter(String), die alle Segmente auf dem Bildschirm ausgibt.

  • camelCaseSplitter("List") führt zu List

  • camelCaseSplitter("ArrayList") führt zu Array List

  • camelCaseSplitter("numberOfElements") führt zu number Of Elements

1.1.11. Der Große Don in der Mitte ☆

Der Große ist der Mittelpunkt der Welt, also erwartet er, dass er in allen Texten auch im Zentrum steht.

Schreibe eine Methode boolean isBigDonInCenter(String), die true liefert, wenn die Zeichenfolge "BigDon" wirklich in der Mitte steht.

Ein paar Beispiele:

  • isBigDonInCenter("BigDon")true

  • isBigDonInCenter("!BigDon!")true

  • isBigDonInCenter("BigBigDonDon")true

  • isBigDonInCenter("x!_BigDonabc")true

  • isBigDonInCenter("stupid BigDon")false

  • isBigDonInCenter("\t\tBigDon ")false

1.1.12. Der Kürzere gewinnt ☆

Der Große Don ist bequem und nutzt nur den kürzesten Rufnamen einer Person.

Schreibe eine Methode String shortestName(String…​ names), die von allen vollständigen Namen den kürzesten Teilstring zurückgibt. Teilstrings sind durch Weißraum getrennt.

Beispiel: shortestName( "Albert Tross", "Nick Olaus", "Jo Ker") liefert "Jo".

1.1.13. Aufgefüllt ☆

Der Große Don benötigt für eine Aufstellung eine Tabelle der folgenden Art:

Al Carpaccio   bezahlt
Döner Schultz  bezahlt
James Bulgur   bezahlt
Bugsy          nicht bezahlt

Schreibe eine Methode printList(String[] names, boolean[] paid), die eine Aufstellung auf dem Bildschirm ausgibt. Im ersten String-Array stehen alle Namen, im zweiten Array Informationen, ob die Person bezahlt hat oder nicht.

Bei der ersten Spalte muss der längste Name extrahiert werden und so viel Leerzeichen generiert werden, sodass die zweite Spalte bündig ist. Die ersten und zweite Spalte wird durch zwei Leerzeichen getrennt.

1.1.14. Vorkommen zählen ☆

Der Große Don hat in einer unbedachten Aktion den Entwickler Dev David ausgeschaltet. Der war gerade dabei eine Methode zu schreiben; die Javadoc ist fertig, aber die Implementierung fehlt.

/**
 * Counts how many times the substring appears in the larger string.
 *
 * A {@code null} or empty ("") String input returns {@code 0}.
 *
 * <pre>
 * StringUtils.countMatches(null, *)       = 0
 * StringUtils.countMatches("", *)         = 0
 * StringUtils.countMatches("abba", null)  = 0
 * StringUtils.countMatches("abba", "")    = 0
 * StringUtils.countMatches("abba", "a")   = 2
 * StringUtils.countMatches("abba", "ab")  = 1
 * StringUtils.countMatches("abba", "xxx") = 0
 * </pre>
 *
 * @param str  the String to check, may be null
 * @param sub  the substring to count, may be null
 * @return the number of occurrences, 0 if either String is {@code null}
 */
public static int countMatches(String str, String  sub) {
}

Implementiere die Methode.

1.1.15. Diamanten bauen ☆☆

Der Große Don mag Diamanten, je größer je besser.

Schreibe ein Programm, was folgende Ausgabe generiert:

   A
  ABA
 ABCBA
ABDEDBA
 ABCBA
  ABA
   A

Prinzipiell soll es möglich sein, die breiteste Stelle anzugeben, was in dem in unserem Beispiel 7 ist. Wir wollen eine Breite ausschließen, die unmöglich mit aufsteigenden Großbuchstaben zu erreichen ist, also soll ABCDEFGHIJKLMNOPQRSTUVWXYZYW…​ das Breiteste sein.

1.1.16. Wörter unterstreichen ☆☆

Immer wieder macht der Große Don seine Familienmitglieder auf Regeln aufmerksam. Er schreibt dazu eine Nachricht und unterstreicht die wichtigen Wörter. Don hat im folgenden Text das Wort "Geld" unterstrichen markiert.

Du musst zuerst Geld machen! Wenn du das Geld hast, bekommst du Macht.
                ----                     ----

Aufgabe:

  1. Lege eine neue Klasse PrintUnderline an.

  2. Schreibe eine neue statische Methode printUnderline(String text, String search), die jede Zeichenkette underline in text wie im oberen Beispiel gezeigt unterstreicht. Bedenke, dass text mehrmals im String vorkommen kann, oder auch keinmal.

1.1.17. Vokale entfernen ☆

Der Große Don möchte nur nur verschlüsselt mit seiner Famile kommunzieren. Ein Sprachwissenschaftler sagte ihm, dass ein Text auch nach dem Entfernen von Vokalen noch verständlich bleibt. Stimmt es, was die Wissenschaftler sagen?

  1. Lege eine neue Klasse RemoveVowel an.

  2. Schreibe eine Klassenmethode String removeVowels(String s), die aus einem übergebenen java.lang.String die Vokale entfernt.

  3. Löse die Aufgabe mit mindestens zwei verschiedenen Varianten.

1.1.18. Gutes Passwort? ☆

Alle schmutzigen Geheimnisse verschlüsselt der Große Don, aber zu oft war sein Passwort zu einfach, und wurde erraten. Der Große Don hat gerlernt das ein sicheres sichere Passwort für seine Geschäfte wichtig ist, doch kann es sich die Regeln nicht so richtig merken: Ein gutes Passwort hat eine gewisse Länge, enthält Sonderzeichen, usw.

  1. Lege eine neue Klasse PasswordTester an.

  2. Schreibe eine Methode isGoodPassword(String), die übliche Kriterien testet. Die Methode soll false zurückgeben, wenn das Passwort nicht gut ist, und true, wenn das Passwort einen guten Aufbau hat. Schlägt ein Test fehl, so soll über über System.err eine Meldung erscheinen. Ein Test fiel, werden die anderen Tests nicht mehr durchgeführt.

1.1.19. Quersumme ☆☆

Da der Große Don oftmals Zahlungen anweist, und befürchtet, jemand könnte die Beträge verändern, greift er zu einem Trick: Neben dem Betrag übermittelt er in einem getrennten Kanal die Quersumme.

Die Quersumme einer Zahl bildet man durch die Addition jeder Ziffer der Zahl. Wenn die Zahl etwa 10938 lautet, so ist die Quersumme 1 + 0 + 9 + 3 + 8 = 21.

  1. Lege eine neue Kasse SumOfTheDigits an.

  2. Schreibe eine Klassenmethode int sumOfTheDigits(long value), die die Quersumme einer Zahl berechnet.

  3. Schreibe eine überladene Klassenmethode int sumOfTheDigits(String value) dazu, die die Ziffern in einem String annimmt.

Welche Methode ist leichter zu implementieren? Welche Methode sollte die andere als Unterprogramm aufrufen?

1.1.20. Ausgabe im Morse-Code ☆

Der Große Don ist schon so alt, dass einige seiner alten Familienmitglieder immer noch im Morse-Code funken.

Ein Morse-Funkspruch besteht aus kurzen und langen Symbolen, die mit . und - angedeutet sind.

Kopiere die folgende Definition in eine neue Klasse MorseCodeEncoder:

// A .-      N -.      0 -----
// B -...    O ---     1 .----
// C -.-.    P .--.    2 ..---
// D -..     Q --.-    3 ...--
// E .       R .-.     4 ....-
// F ..-.    S ...     5 .....
// G --.     T -       6 -....
// H ....    U ..-     7 --...
// I ..      V ...-    8 ---..
// J .---    W .--     9 ----.
// K -.-     X -..-
// L .-..    Y -.--
// M --      Z --..

Schreibe eine statische Methode morseCode(String), die einen String annimmt und dann in Morse-Code konvertiert. Jedes Zeichen der Zeichenfolge soll im entsprechende Morse-Code ausgeben werden. Jeder Block soll dabei in der Ausgabe durch ein Leerzeichen getrennt sein. Nicht bekannte Zeichen werden übersprungen. Kleinbuchstaben sollen wie Großbuchstaben gewertet werden.

1.1.21. Die Caesar-Verschlüsselung ☆☆

Der Große Don hat von einer Verschlüsselung erfahren, die schon Gaius Julius Caesar verwendet haben soll. Da er den römischen Feldherrn bewundert, will auch auch seine Texte so verschlüsseln.

Bei der sogenannten Caesar-Verschlüsselung verschiebt man jedes Zeichen um drei Positionen im Alphabet, das heißt, aus A wird D, aus B wird E und so weiter. Am Ende des Alphabets beginnen wir wieder von vorne und so ergibt X → A, Y → B, Z → C.

  1. Lege eine neue Klasse Caesar an.

  2. Implementiere eine Methode String caesar(String s, int rotation), die die Verschlüsselung vornimmt.rotation ist dabei die Verschiebung, die beliebig sein sollte, nicht nur 3 wie aus dem Eingangsbeispiel.

  3. Schreibe eine Methode String decaesar(String s, int rotation), die die Verschlüsselung wieder zurücknimmt.

  4. Die Caesar-Verschlüsselung fällt ist die Klasse der Verschiebechiffre. Sind sie dem Großen Don zu empfehlen?

1.1.22. Komprimieren ☆☆☆

Um das Datenvolumen zu reduzieren, werden Dateien oft komprimiert. Es gibt unterschiedliche Kompressionsalgorithmen, einige sind verlustbehaftet, andere arbeiten ohne Verlust. Verlustbehaftete Kompression findet man z. B. bei Bildern, JPEG ist ein gutes Beispiel. In Abhängigkeit von dem Grad der Kompression verschlechtert sich die Bildqualität. Eine sehr hohe Kompression führt beim JPEG-Verfahren zu einem Bild mit starken Artefakten.

Eine einfache verlustfreie Kompression ist die Lauflängenkodierung. Das Prinzip dabei ist, Folge von gleichen Symbolen zusammenzufassen, dass nur noch die Anzahl und das Symbol geschrieben wird. Das Grafikformat GIF nutzt z. B. diese Form der Kompression. Daher sind Bilder mit vielen einfarbigen Zeilen auch kleiner als zum Beispiel Bilder, in denen jeder Bildpunkt eine andere Farbe hat.

Die nächste Aufgabe handelt um Lauflängenkodierung. Nehmen wir an, ein String besteht aus einer Folge von . (Punkt) und - (Minuszeichen), etwa

...----....--.-.-.

Um die Länge von Zeichenketten zu verkürzen können wir zunächst die das Symbol gefolgt von der Anzahl Symbole schreiben. Die Zeichenfolge könnte verkürzt werden zu

.3-4.4-2.1-1.1-1.1.
  1. Lege eine neue Klasse SimpleStringCompressor an.

  2. Schreibe eine statische Methode String compress(String), die Folgen von . und - nach dem beschriebenen Algorithmus kodiert: erst kommt das Zeichen, dann die Anzahl.

  3. Schreibe einen Dekodierer String decompress(String), der der komprimierten String wieder auspackt. Es soll uncompress( compress( input ) ) gleich input sein.

Erweiterungen:

  • Das Programm soll alle nicht-Ziffern verarbeiten können.

  • Verfeinere das Programm, dass die Zahl ausbleibt, wenn das Zeichen nur genau einmal vorkommt.

1.1.23. Der Palindrom-Test ☆

Ein Palindrom ist ein Wort, das sich von vorne wie von hinten gleich liest, etwa Otto oder auch 121.

Schreibe ein Java-Programm, welches untersucht, ob die als Kommandozeilen-Argumente angegebenen Wörter Palindrome sind.

  • Lege eine neue Klasse PalindromTester an.

  • Implementiere eine Methode boolean isPalindrom(String s).

  • Erweitere das Programm um eine Klassenmethode isPalindromCaseInsensitive(String s), sodass der Test unabhängig von der Groß-/Kleinschreibung wird.

  • Jetzt sollen auch noch Leerzeichen überlesen werden, sodass A man a plan a canal Panama erkannt wird. Nenne die Methode isPalindromIgnoreSpace(String s).

1.1.24. Blumenwiese ☆☆

Im Herzen ist der Großen Don Romantiker und er mag Blumen. Er findet von Joan G. Stark eine Grafik und wünscht sich, dass er jede der Blumen so oft er möchte nebeneinander setzen kann.

                _
              _(_)_                          wWWWw   _
  @@@@       (_)@(_)   vVVVv     _     @@@@  (___) _(_)_
 @@()@@ wWWWw  (_)\    (___)   _(_)_  @@()@@   Y  (_)@(_)
  @@@@  (___)     `|/    Y    (_)@(_)  @@@@   \|/   (_)\
   /      Y       \|    \|/    /(_)    \|      |/      |
\ |     \ |/       | / \ | /  \|/       |/    \|      \|/
\\|//   \\|//   \\\|//\\\|/// \|///  \\\|//  \\|//  \\\|//
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Aufgabe:

  1. Kopiere die Blumen in einen String.

  2. Schreibe ein Programm, so dass man die komplette Reihe von Blumen beliebig oft nebeneinander setzen kann.

  3. Es gibt 8 Sorten von Blumen und wir können sie durchnummerieren von 1 bis 8. Kodiert man die Reihenfolge als String sind die Blumen "12345678" angezeigt. Es soll nun möglich sein andere Reihenfolgen darzustellen und Blumen häufiger darzustellen, etwa durch die Kodierung "8383765432".

1.1.25. Wiederholungen erkennen ☆☆☆

Der Große Don mag keine Schwätzer, die sich nur Wiederholen.

Schreibe eine Methode boolean repeating(String), die Wiederholungen erkennt. Beispiele:

  • repeating("DonDon") liefert true.

  • repeating("Don") liefert false.

  • repeating("Dondon") liefert false.

  • repeating("DonDiDon") liefert false.

  • repeating("DonDiDonDi") liefert true.

  • repeating("abababa") liefert true.

  • repeating("* * * * * ") liefert true.

1.1.26. Zeilengrenzen beschränken ☆☆

Der Große Don hat eine Pizzeria beschlagnahmt und da ist ihm viel schmales Bonpapier in den Hände gefallen. Jetzt muss er alle seine Texte in der Breite reduzieren.

Schreibe eine Klasse WordWrapper mit einer statischen Methode String wrapWord(String s, int len), die eine Zeichenkette s in kleine Teilzeichenketten der Länge len zerlegt und mit Return getrennt wieder zurückgibt.

Ein Beispiel:

String s = "Ich habe nichts gesehen, ich habe nichts gehört, " +
"ich war nie dort, und wenn doch, hab ich geschlafen.";
System.out.println( wrap( s, 30 ) );

Das liefert bei einer maximalen Zeilenlänge von 30 folgender Ausgabe:

Ich habe nichts gesehen, ich
habe nichts gehört, ich war
nie dort, und wenn doch, hab
ich geschlafen.

1.1.27. Quizz: Wie viele String-Objekte? ☆

Wie viele String-Objekte gibt es im folgendem Programmcode?

String str1 = "tutego";
String str2 = new String( "tutego" );
String str3 = "tutego";
String str4 = new String( "tutego" );

1.1.28. Schokoladig umhüllt ☆☆

Der Große Don mag Obstspieße mit Schokolade überzogen. Sara bekommt die Aufgabe die Früchte zu glasieren, wobei sie unterschiedliche Schichten von dunkler und heller Schokolade bildet.

Bambi prüft, ob die die Schichten korrekt sind — sieht sie dhFhd weiß sie, dass die Frucht F erst eine Schicht helle, dann eine Schicht dunkle Schokolade bekommen hat. Bei dhhd fehlt die Frucht und der Große Don wäre sehr entäuscht, und bei ddhFh ist die Schicht kaputt, was auch nicht richtig ist.

Schreibe eine rekursive Methode checkChocolate(String), die prüft, ob links und rechts der gleiche Typ Schokolade ist und sich in der Mitte die Frucht befindet.

Tipp: Prüfe die Symbole am Anfang und Ende, verkleinere den String und prüfe erneut.

Optional: Erweitere das Programm, dass der String eine Fläche ist, etwa

String fruit =
"ddddd\n" +
"dhhhd\n" +
"dhFhd\n" +
"dhhhd\n" +
"ddddd" ;

1.2. Dynamische Strings mit StringBuilder

Während String-Objekte immutable sind, lassen sich Objekte vom Typ java.lang.StringBuilder modifizieren. Gleiches gilt für StringBuffer, doch dieser Typ ist API-gleich und für die Übungen nicht relevant.

1.2.1. Leerzeichenkomprimierer ☆☆

Oftmals sind zu viele Leerzeichen im Text überflüssig und können auf nur ein Leerzeichen verkürzt werden. Aus einem String "Hallo Welt " kann dann "Hallo Welt " werden.

Schreibe eine statische Methode StringBuilder compressSpace(StringBuilder sb), die mehr als zwei Leerzeichen in dem übergebenen StringBuilder zu einem Leerzeichen zusammenschmelzen lässt. Die Übergabe sb soll mit return sb; zurückgegeben werden, die Veränderung soll direkt am StringBuilder erfolgen.

Optionale Erweiterungen:

  • Leerzeichen ganz am Anfang und ganz am Ende sollen komplett weggeschnitten werden.

  • Wenn ein Tabulator vorkommt, soll dieses wie ein Leerzeichen gewertet werden, sodass ein String wie "hallo \t welt" zu "hallo welt" wird.

1.2.2. Knack ☆

Meldungen über Funk haben oft ein Knacksen, das störtet dem Großen Don.

Simuliere ein Knacksen, in dem in einem beliebigen gegebenen String in willkürlichen Abständen "♬KNACK♪" eingebaut wird.

public static String knack( String text ) { ... }
public static String deKnack( String text ) { ... }

Die Methode knack(…​) fügt das Knacken ein, und deKnack(…​) entfernt das Knacken wieder.

1.3. Einfache Zerlegung von Zeichenketten, Tokenizer

1.3.1. Gleichberechtigung ☆

Der Große Don liest Protokolle und ihm fällt auf, dass seine Tocher Marietta Angel Eyes fast immer mit Rusty Duke auftaucht. Er hat einen Verdacht, dass beide was miteinander zu tun haben. Das gefällt ihm nicht.

Schreibe eine Methode boolean isMariettaMeetingRusty(String text), die prüft, ob der Name "Marietta" und "Rusty" in einem Text vorkommt und dann die beiden Wörter höchstens 10 Wörter von einander getrennt sind. Wir nehmen vereinfacht an, dass beide Namen nur einmal vorkommen.

1.3.2. Eissorten erkennen ☆

Natürlich mag der Große Don Eis, er spricht oft von "Vanilleeis", "Erdbeer Eis", "Scholokadeneis".

Neue Familienmitglieder wissen am Anfang nicht, welche Sorten der Große Don mag. Daher hören Sie genau zu, um aus dem Wort vor "Eis" zu erfahren, welche Sorten er mag.

Schreibe eine Methode String iceCreamFlavor(String) die einen Text bekommt, in dem maximal eine Eissorte vorkommen kann. Das Ergebnis der Methode ist der Name der Eissorte, die entweder vor dem Wort "Eis" stehen kann, oder als Teil des String selbst ist.

Beispiele:

  • iceCreamFlavor("Ein cremiges Vanilleeis erinnert mich an einen Betonmischer") liefert "Vanille".

  • iceCreamFlavor("Luigi habe ich kaltgestellt wie Erdbeeren auf meinem Erdbeer Eis") liefert "Erdbeer".