Java Videotraining Werbung

Videotraining Spring 3 Boot Werbung

1. Zeichenkettenverarbeitung

Zum Speichern von Zeichen und Zeichenfolgen stehen in Java die Typen char, Character, String und StringBuilder bereit. Der Einsatz der Datentypen muss geübt werden, denn jeder Typ hat seine Berechtigung. Die Aufgaben bringen den Lesern die Vor- und Nachteile der einzelnen Datentypen nahe.

Voraussetzungen

  • API von String und StringBuilder sicher nutzen können

  • API von String und StringBuilder sicher nutzen können

  • erkennen, wann String und StringBuilder besser geeignet ist

Verwendete Datentypen in diesem Kapitel:

1.1. Die Klasse String und ihre Eigenschaften

String ist nicht nur ein Datentyp, der für immutable Zeichenfolgen steht, sondern die Klasse bietet auch eine große Anzahl von Methoden. Wer die Methoden kennt und zu nutzen weiß, kann sich viel Arbeit sparen.

1.1.1. HTML-Elemente aufbauen mit einfacher Konkatenation ⭐

Zur Erinnerung: In HTML werden für Auszeichnungen Tags eingesetzt, ein Beispiel ist <strong><em>Emphasized and Italics</em></strong>.

Aufgabe:

  1. Schreibe eine neue Methode htmlElement(String tag, String body), die einen String body mit einem Start- und End-Tag tag einrahmt und als neuen String zurückgibt. Es gibt folgende Sonderbehandlung:

    • Ist tag gleich null oder leer ("") so wird nur der body betrachtet und keine Start-End-Tags geschrieben.

    • Ist body gleich null, so gilt das wie ein übergebener Leer-String.

  2. Schreibe zwei neue Methoden strong(String) und emphasized(String), die im Hintergrund mit htmlElement(…​) arbeiten und ein <strong> respektive <em> erzeugen.

Beispiel:

  • htmlElement( "strong", "strong is bold" )"<strong>strong is bold</strong>"

  • strong( emphasized( "strong + emphasized" ) )"<strong><em>strong + emphasized</em></strong>"

  • htmlElement( "span", null )"<span></span>"

  • htmlElement( "", "no" )"no"

  • htmlElement( null, "not strong" )"not strong"

  • htmlElement( null, null )""

Hinweis: Es gibt durchaus einige Anforderungen an Tag-Namen, die ein richtiges Programm prüfen könnte. So dürfen Tag-Namen nur die Ziffern 0 bis 9 sowie Groß- und Kleinbuchstaben enthalten. Diese Fälle können ignoriert werden.

1.1.2. Sichere Übermittlung durch Verdoppelung der Zeichen prüfen ⭐

Bamboo Blobfish nutzt einen Typendrucktelegraf, um Bonny Brain wichtige Nachrichten mitzuteilen. Da es auf jedes Zeichen ankommt, sendet Bamboo alle Zeichen zur Sicherheit zweimal hintereinander.

Check safe transmission by doubling characters

Aufgabe:

  • Schreibe eine Methode int isEveryCharacterTwice(String), die prüft, ob jedes Zeichen im String zweimal hintereinander vorkommt.

    • Ist die Anzahl der Symbole ungerade, ist die Nachricht falsch und die Rückgabe der Methode 0.

    • Kommt jedes Zeichen zweimal vor, ist die Antwort eine beliebige positive Zahl. ˗ Wenn ein Zeichen nicht zweimal hintereinander vorkommt, gibt die Methode die Position mit der ersten falschen Stelle zurück, allerdings negiert.

Beispiele:

  • isEveryCharacterTwice("eehhrrwwüürrddiiggeerr$$ccaappttaaiinn")1

  • isEveryCharacterTwice("ccapptttaaiinn")-3

  • isEveryCharacterTwice("222")0

  • isEveryCharacterTwice(null)NullPointerException

Dass ein negativer Index gewisse Stellen markiert, ist auch in der Java-Bibliothek zu finden. Die Arrays-Klasse bietet binarySearch(…​), die in einem sortierten Array etwas sucht, und wenn die Methode das Element findet, die Fundstelle zurückgibt; falls binarySearch(…​) den Eintrag nicht findet, wird die negierte Position zurückgegeben, an der das Element eingefügt werden könnte.

1.1.3. Y und Z vertauschen ⭐

Captain CiaoCiao tippt auf seiner Tastatur einen längeren Text, und spät fällt ihm auf, dass statt des deutschen Tastaturlayouts das englische aktiviert ist. Jetzt sind »y« und »z«, bzw. »Y« und »Z« vertauscht. Der Text muss korrigiert werden.

Swap Y and Z

Aufgabe:

  1. Lege eine neue Klasse YZswapper an.

  2. Setze in die Klasse eine neue Klassenmethode void printSwappedYZ(String string), die einen übergebenen String auf den Bildschirm bringt, aber den Buchstaben »y« als »z«, »z« als »y«, »Y« als »Z« und »Z« als »Y« ausgibt. Es geht nicht darum, einen String aus der Methode zurückzuliefern!

  3. Schreibe nicht nur eine Variante, sondern versuche, mindestens zwei Varianten zu programmieren. Es gibt zum Beispiel, die Möglichkeit die Zeichen mit if-else zu prüfen oder mit switch-case.

Beispiele:

  • printSwappedYZ("yootaxz") ergibt auf dem Bildschirm die Ausgabe zootaxy und

  • printSwappedYZ("Yanthoxzl") die Ausgabe Zanthoxyl.

1.1.4. Trotzige Antworten geben ⭐

Tony der Trotzige ist für die Aktivitäten auf dem Schwarzmarkt von Captain CiaoCiao zuständig, doch er wird geschnappt und von der Polizei verhört. Um die Polizisten zu nerven, wiederholt er alles, was sie sagen, und setzt ein »No idea!« hintendran. Fragt der Polizist: »Where is the illegal whiskey distillery?«, sagt Tony: »Where is the illegal whiskey distillery? No idea!«

Give defiant answers

Aufgabe:

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

  2. Abhängig von der Eingabe sollen drei Fälle unterschieden werden:

    • Wenn die Eingabe mit einem ? endet, dann gib auf dem Bildschirm aus, was von der Eingabe kommt, und hänge aber " No idea!" hinten an.

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

    • Kommt von der Eingabe die spezielle Eingabe "No idea?", und das unabhängig von der Groß-/Kleinschreibung, erwidert Tony trotzig: "Aye!"

1.1.5. Zeichenfolgen auf Palindrom-Eigenschaft testen ⭐

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

Dass es überhaupt solche Wörter und sogar Sätze gibt, amüsiert Captain CiaoCiao, kann er damit doch die Gesellschaft unterhalten. Allerdings legt man ihm immer wieder Zeichenfolgen vor, die keine Palindrome sind. Daher müssen alle Wörter vorher getestet werden.

PalindromeTester

Aufgabe:

  • Schreibe ein Java-Programm, das untersucht, ob eine Zeichenkette ein Palindrom ist.

    • Lege eine neue Klasse PalindromeTester an.

    • Implementiere eine statische Methode boolean isPalindrome(String s).

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

    • Jetzt sollen auch alle Zeichen ignoriert werden, die keine Buchstaben oder Ziffern sind. Bei der Feststellung hilft Character.isLetterOrDigit(char). Damit kann man auch Sätze wie »A man a plan a canal Panama« oder »Pepe in Tahiti hat nie Pep« oder »Sei fies – stets sei fies!« prüfen. Nennen wir die Methode isPalindromeIgnoringNonLettersAndDigits(String).

1.1.6. Prüfen, ob Captain CiaoCiao in der Mitte steht ⭐

Captain CiaoCiao ist der Mittelpunkt der Welt, also erwartet er, dass er in allen Texten auch im Zentrum steht.

Check if Captain CiaoCiao is in the middle

Aufgabe:

  • Schreibe eine Methode boolean isCiaoCiaoInMiddle(String), die true liefert, wenn die Zeichenfolge "CiaoCiao" in der Mitte steht.

Beispiele:

  • isCiaoCiaoInMiddle("CiaoCiao")true

  • isCiaoCiaoInMiddle("!CiaoCiao!")true

  • isCiaoCiaoInMiddle("SupaCiaoCiaoCute")true

  • isCiaoCiaoInMiddle("x!_CiaoCiaoabc")true

  • isCiaoCiaoInMiddle("\tCiaoCiao ")true

  • isCiaoCiaoInMiddle("BambooCiaoCiaoBlop")false

  • isCiaoCiaoInMiddle("Bernie und Ert")false

1.1.7. Den kürzesten Namen im Array finden ⭐

Bonny Brain nutzt nur den kürzesten Rufnamen einer Person.

ShortName

Aufgabe:

  • Schreibe eine Methode String shortestName(String... names), die von allen vollständigen Namen den kürzesten Teil-String zurückgibt. Der String kann auch genau ein Leerzeichen enthalten, wenn der Name zusammengesetzt ist. Anders gesagt: Es gibt Strings mit einem Namen oder Strings mit zwei Namen.

  • Wenn es keine Namen gibt, ist die Antwort ein leerer String.

  • Das Vararg-Array darf nicht null sein, und kein String im Array darf null sein.

Beispiel:

  • shortestName("Albert Tross", "Blowfish", "Nick Olaus", "Jo Ker")"Jo"

1.1.8. String-Vorkommen zählen ⭐

Captain CiaoCiao 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("aaaa", "aa")  = 2
 * StringUtils.countMatches("abba", "ab")  = 1
 * StringUtils.countMatches("abba", "xxx") = 0
 * </pre>
 *
 * @param string  the String to check, may be null
 * @param other   the substring to count, may be null
 * @return the number of occurrences, 0 if either String is {@code null}
 */
public static int countMatches( String string, String other ) { return null; }

Hinweis: Das * in der Javadoc symbolisiert eine beliebige Übergabe.

Aufgabe:

  • Implementiere die Methode.

1.1.9. Die größere Mannschaft ermitteln ⭐

Bonny Brain studiert alte Logbücher, in denen die Stärke ihrer Mannschaft und die der gekaperten Schiffe steht:

|-|||
|-||
|||-|||
|||||-||

Jedes Crew-Mitglied ist durch einen Strich symbolisiert, ein Minuszeichen trennt die Mannschaftsgröße. Links steht die Anzahl Personen auf dem eigenen Schiff, rechts die Anzahl des überfallenen Schiffs.

Determine the larger crew size

Aufgabe:

  • Die Striche sind für Bonny Brain nicht gut zu lesen. Schreibe ein Programm, das die Kodierung deutlich macht:

    |-||| => Raided ship had a larger crew, difference 2
    |-|| => Raided ship had a larger crew, difference 1
    |||-||| => Ships had the same crew size
    |||||-|| => Pirate ship had a larger crew, difference 3

1.1.10. Diamanten bauen ⭐⭐

Captain CiaoCiao mag Diamanten, je größer desto besser.

Build diamonds

Aufgabe:

  • Schreibe ein Programm, das folgende Ausgabe generiert:

       A
      ABA
     ABCBA
    ABCDCBA
     ABCBA
      ABA
       A

    Über eine Abfrage auf der Konsole soll es möglich sein, die maximale Breite des Diamanten festzulegen. In unserem Beispiel ist das die 7 — die Länge des String ABCDCBA. Es sollen nur Angaben für die Breite akzeptiert werden, die mit Strings aus auf- und wieder absteigenden Großbuchstaben zu erreichen sind, also maximal die Länge von ABCDEFGHIJKLMNOPQRSTUVWXYZYXWVU…​BA.

1.1.11. Auf ein gutes Passwort prüfen ⭐

Alle schmutzigen Geheimnisse verschlüsselt Captain CiaoCiao, aber zu oft war sein Passwort zu einfach und wurde erraten. Er hat gelernt, dass ein sicheres Passwort für seine Geschäfte wichtig ist, doch kann er sich die Regeln nicht so richtig merken: Ein gutes Passwort hat eine gewisse Länge, enthält Sonderzeichen usw.

Check for a good password

Aufgabe:

  1. Lege eine neue Klasse PasswordTester an.

  2. Schreibe eine Methode isGoodPassword(String), die einige 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 System.err eine Meldung erscheinen und es sollen keine weiteren Prüfungen stattfinden.

1.1.12. Erdnussbutterkekse backen ⭐⭐

Kurz vor dem Fest trifft sich die Crew bei Captain CiaoCiao, um Erdnussbutterkekse zu backen. Die Hobbybäcker bringen entweder Erdnussbutter, Zucker oder Eier mit. Als sie ankommen, setzen sie sich der Reihe nach an einen Tisch und möchten anfangen zu backen.

Gegeben ist eine Liste aller Zutaten, die die Hobbybäcker mitgebracht haben. Die Liste wird als String repräsentiert, wobei P für Erdnussbutter steht, S für Zucker und E für Ei. Der String könnte lauten: PSESEPESP oder auch PPPEEESSS.

Gebacken werden kann nur, wenn drei Hobbybäcker mit Erdnussbutter, Zucker und Ei nebeneinander sitzen, wobei die Reihenfolge egal ist.

Bake Peanut Butter Cookies

Aufgabe:

  • Ermittele, wie oft Erdnussbutterkekse gebacken werden können, also die drei Zutaten direkt nebeneinander in beliebiger Reihenfolge zusammenkommen.

  • Einige Hobbybäcker haben nicht richtig zugehört und bringen ganz andere Zutaten mit, wie Rum, Lakritz oder marinierten Aal. Mit ihnen lassen sich keine Erdnussbutterkekse backen.

Beispiele:

  • "PSESEPESP" → 3

  • "PPPEEESSS" → 0

  • "SEPEPLSEE" → 1

1.1.13. Quersumme berechnen ⭐

Da Bonny Brain oftmals Zahlungen anweist und befürchtet, jemand könnte die Beträge verändern, greift sie zu einem Trick: Neben dem Betrag übermittelt sie 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.

Calculate sum of digits

Aufgabe:

  1. Lege eine neue Klasse SumOfTheDigits an.

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

  3. Schreibe eine überladene Klassenmethode int digitSum(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.14. Texte entspalten ⭐⭐

Captain CiaoCiao scannt alte Logbücher ein, doch die waren ursprünglich in Spalten. Nach der OCR-Texterkennung bleiben die Spalten erhalten.

Da das nicht gut zu lesen ist, sollen die zwei Spalten erkannt und in regulären Fließtext ohne Spalten übersetzt werden.

Decolumnize texts

Aufgabe:

  • Schreibe eine Methode decolumnize(String), die nach der Weißraum für die Trennung der Spalten sucht und aus einem String mit Text in zwei Spalten einen Text ohne Spalten liefert. Es ist im Vorfeld nicht bekannt, wo die Trennung der Spalten ist, das muss das Programm ermitteln.

Beispiel:

I’m dishonest, and a to watch out for,
dishonest man you    because you can
can always trust to  never predict when
be dishonest.        they’re going to do
Honestly, it’s the   something incredibly
honest ones you want stupid.

I’m dishonest, and a
dishonest man you
can always trust to
be dishonest.
Honestly, it’s the
honest ones you want
to watch out for,
because you can
never predict when
they’re going to do
something incredibly
stupid.

Jede Spalte ist durch mindestens ein Leerzeichen getrennt. Bedenke, dass die rechte und linke Seite »halbe« Leerzeilen haben können!

1.1.15. Eine Wiese mit Lieblingsblumen zeichnen ⭐⭐

Captain CiaoCiao möchte sein Schiff verschönern und mit Blumen verzieren. Er findet eine Grafik von Joan G. Stark als Vorlage und überlegt, wie er den Malern und Anstreichern mitteilen kann, welche Muster er in der Kabine wünscht.

                _
              _(_)_                          wWWWw   _
  @@@@       (_)@(_)   vVVVv     _     @@@@  (___) _(_)_
 @@()@@ wWWWw  (_)\    (___)   _(_)_  @@()@@   Y  (_)@(_)
  @@@@  (___)     `|/    Y    (_)@(_)  @@@@   \|/   (_)\
   /      Y       \|    \|/    /(_)    \|      |/      |
\ |     \ |/       | / \ | /  \|/       |/    \|      \|/
\\|//   \\|//   \\\|//\\\|/// \|///  \\\|//  \\|//  \\\|//
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Draw a meadow with favorite flowers

Aufgabe:

  1. Kopiere die Blumen in einen String. Tipp: Lege einen String wie String flower = ""; an, setze die Blumenreihe in die Zwischenablage, und füge sie in der IDE zwischen die Anführungszeichen ein; IntelliJ und Eclipse werden dann die Sonderzeichen wie \ und \n selbständig kodieren. Mit den Textblöcken wird es noch einfacher.

  2. Es gibt 8 Sorten von Blumen, und wir können sie durchnummerieren von 1 bis 8. Die Reihenfolge kodieren wir als String, zum Beispiel "12345678". Es soll nun möglich sein, die Reihenfolge zu ändern und Blumen mehrfach vorkommen zu lassen, etwa durch die Kodierung "8383765432". Ist eine Kennung falsch, soll für sie automatisch immer die erste Blume erscheinen.

Beispiele:

  • "838" führt zu

       _    _(_)_      _
     _(_)_ (_)@(_)   _(_)_
    (_)@(_)  (_)\   (_)@(_)
      (_)\      `|/   (_)\
         |      \|       |
        \|/      | /    \|/
      \\\|/   \\\|//  \\\|/
    ^^^^^^^^^^^^^^^^^^^^^^^
  • "ABC9" führt zu

      @@@@   @@@@   @@@@   @@@@
     @@()@@ @@()@@ @@()@@ @@()@@
      @@@@   @@@@   @@@@   @@@@
       /      /      /      /
    \ |    \ |    \ |    \ |
    \\|//  \\|//  \\|//  \\|//
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Halte in einem Array die Stellen für den Übergang zwischen den Blumen fest.

1.1.16. Wiederholungen erkennen ⭐⭐⭐

Captain CiaoCiao blättert in einem Buch und findet Muster der Art 🌼🌻🌼🌻🌸🌼🌻🌼🌻🌸🌼🌻🌼🌻🌸. Wie beruhigend für ihn. Er möchte Stempel für den Druck herstellen, um sich solche Musterfolgen selbst drucken zu können. Natürlich sollen die Kosten reduziert werden, und der Stempel soll selbst keine Wiederholungen von Symbolen enthalten. Für gegebene Musterfolgen soll ein Programm entwickelt werden, das die minimale Folge von Symbolen ermittelt, die auf den Stempel müssen.

Aufgabe:

  • Schreibe eine Methode String repeatingStrings(String), die im Fall einer Wiederholung die sich wiederholende Zeichenfolge als Rückgabe liefert, sonst null, falls sich keine Teilfolge wiederholt.

Beispiele:

  • repeatingStrings("🌼🌼🌼") liefert "🌼".

  • repeatingStrings("🌼🌻""🌼🌻""🌼🌻") liefert "🌼🌻".

  • repeatingStrings("Ciao"+"Ciao") liefert "Ciao".

  • repeatingStrings("Captain CiaoCiaoCaptain CiaoCiao") liefert "Captain CiaoCiao".

  • repeatingStrings("🌕🌔🌓🌑") liefert null

  • repeatingStrings("CaptainCiaoCiaoCaptain") liefert null

  • repeatingStrings("🌼") liefert null

  • repeatingStrings("") liefert null

  • repeatingStrings(null) liefert null

Hinweis: repeatingStrings(…​) soll die kürzeste sich wiederholende Zeichenfolge liefern.

1.1.17. Zeilengrenzen beschränken und Zeilen umbrechen ⭐⭐

Bonny Brain steigt in der Kommunikation auf Brieftauben um, und da kann das Papier nicht sehr groß sein. Jetzt müssen alle Texte in der Breite reduziert werden.