6.10 Lösungen
 
Aufgabe 1

Download:
AnzahlVonE1.java

class AnzahlVonE1 {

  public static void main(String[] args) {
    System.out.print("Geben Sie einen Text ein:");
    String text = Console.in.readLine();
    int anzahl = 0;
    double haeufigkeit;
    for (int i = 0; i < text.length(); i++) {
      if (text.charAt(i) == 'e') {
        anzahl++;
      }
    }
    haeufigkeit = (double) anzahl / text.length();
    System.out.println("Anzahl der e's: " + anzahl);
    System.out.println("Rel. Haeufigkeit: " + haeufigkeit);
  }
}
Bemerkungen

Download:
AnzahlVonE2.java

Der Quellkode ist zum größten Teil selbsterklärend. Auf drei Punkte sei aber verwiesen.
  • Wenn der Text große 'E's und kleine 'e's enthält, so werden nur die klein geschriebenen gezählt. Wenn man beide, groß und klein geschrieben gezählt haben will, so ersetzt man
    (text.charAt(i) == 'e')
    in der if-Bedingung durch:
    (text.toLowerCase().charAt(i) == 'e').
    Der gesamte Text wird zu einem Kleinbuchstabentext konvertiert (Der Inhalt der Variablen text bleibt für die weitere Bearbeitung unverändert!), danach wird für diesen Kleinbuchstabentext die Methode charAt(int i) aufgerufen.
     
  • Da wir beim Einlesen des Textes die Klassen-Methode readLine() benutzen, enthält der Text u.U. auch  Leerzeichen. Die relative Häufigkeit muss dann entsprechend interpretiert werden.
     
  • Die Rechenoperator '/' ist ähnlich wie der '+' - Operator überladen. haeufigkeit = anzahl / text.length() ist eine Ganzzahldivision, liefert in unserem Fall für die Variable haeufigkeit immer den Wert 0. Ist Dividend oder Divisor oder sind beide Fliesskommazahlen, dann liefert '/' selbst eine Fliesskommazahl. Durch einen Typ - Cast oder einfach kurz durch einen Cast können wir erzwingen, dass z.B. eine Variable vom Typ int für die nachfolgende Termauswertung als Variable vom Typ double gewertet wird. Wir erreichen dies durch das Vorstellen von (double). Mehr über Casten erfahren Sie im nächsten Kapitel 17 Casten.
    statt:
    int haeufigkeit = anzahl / text.length();
    schreiben wir
    double haeufigkeit = (double) anzahl / text.length();
Eine Variante Wir ändern das Programm so ab, dass der Benutzer gefragt wird, welchen Buchstaben er gezählt haben will.
 
Download:
AnzahlVonE3.java
import info1.Console;

class AnzahlVonE3 {

  public static void main(String[] args) {
    System.out.print("Geben Sie einen Text ein:");
    String text = Console.in.readLine();
    System.out.print("Welcher Buchstabe soll 
                      gezaehlt werden? ");
    char buchstabe = Console.in.readWord().charAt(0);
    int anzahl = 0;
    double haeufigkeit;
    for (int i = 0; i < text.length(); i++) {
      if (text.charAt(i) == buchstabe) {
        anzahl++;
      }
    }
    haeufigkeit = (double) anzahl / text.length();
    System.out.println("Anzahl der e's: " + anzahl);
    System.out.println("Rel. Haeufigkeit: " + haeufigkeit);
  }
}
Aufgabe 2

Download:
DreiChinesen.
java

import info1.Console;

class DreiChinesen {

  public static void main(String[] args) {
    System.out.print("Geben Sie einen Text ein 
                      (Kleinbuchstaben): ");
    String text = Console.in.readLine();
    System.out.print("Durch welchen Buchstaben 
                      sollen alle Vokale ersetzt werden? ");
    char b = Console.in.readWord().charAt(0);
    String textNeu ="";
    char z;
    boolean vokal;
    for(int i = 0; i < text.length(); i++) {
      z = text.charAt(i);
      vokal = (z == 'a' || z == 'e' || z == 'i' 
                        || z == 'o' || z == 'u');
      if(vokal) {
        textNeu = textNeu + b;
      } else {
        textNeu = textNeu + z;
      }
    }
    System.out.println(textNeu);
  }
}
Bemerkungen Das Programm setzt nur klein geschriebene Vokale um, deshalb auch die Bemerkung am Anfang des Programms, nur Sätze mit kleinen Buchstaben einzugeben. Dem Leser sei es überlassen, das Programm so abzuwandeln, dass auch große Buchstaben ersetzt werden können. Interessant ist, wie der neue Text aufgebaut wird. Es wird ein neues String - Objekt textNeu deklariert und mit einem Leerstring initialisiert.  Dieses Objekt wird zum neuen Text aufgebaut, in dem Buchstabe für Buchstabe des alten Textes bzw. der Ersetzungsvokal  hinzugefügt wird.
Es gibt noch eine Alternative zu der gezeigten Lösung; dazu verwenden wir die bis jetzt noch nicht verwendete String - Methode
replace(char alt, char neu). Wird diese Methode für einen String - Objekt aufgerufen, so wird ein neues String - Objekt erzeugt, in dem alle Zeichen alt durch die Zeichen neu ersetzt wurden.
 
Download:
DreiChinesenALT. java
import info1.Console;

public class DreiChinesenALT {

  public static void main (String[] args) {
    System.out.print("Geben Sie einen Text ein 
                      (Kleinbuchstaben): ");
    String text = Console.in.readLine();
    System.out.print("Durch welchen Buchstaben sollen 
                      alle Vokale ersetzt werden? ");
    char b = Console.in.readWord().charAt(0);
    String textNeu = text;
    textNeu = textNeu.replace('a',b);
    textNeu = textNeu.replace('e',b);
    textNeu = textNeu.replace('i',b);
    textNeu = textNeu.replace('o',b);
    textNeu = textNeu.replace('u',b);
    System.out.println(textNeu);
  }
}
  Der Quellkode es Programms zeigt, dass 6 mal das Objekt textNeu erzeugt wird. Die Referenz auf das 'alte' textNeu geht dabei verloren, was nicht weiter schlimm ist, denn der Garbage Collector (gc) der Java-VM findet diese nicht mehr referrenziierten Objekte und bereinigt den Speicher, in dem er den Speicherplatz, an dem die nicht mehr verwendeten Objekte liegen, frei gibt. Dieser Vorgang geht automatisch und muss vom Programmierer nicht extra angestoßen werden.  Das Programm hat aber einen Nachteil: Ist der Wert von b etwa 'i' dann werden bei einem der replace(..) - Aufrufe alle 'i's durch 'i's ersetzt. Dies kann man verhindern, wenn wir jede Zeile vom Typ

textNeu = textNeu.replace('i',b);

durch

if(b!='i') {
  textNeu = textNeu.replace('i',b);
}

ersetzen. Bei der Download - Datei ist diese Veränderung schon berücksichtigt.
 

Aufgabe 3

Download:
Palindrom.java
import info1.Console;
public class Palindrom{
  public static void main(String[] args) {
  System.out.println("Geben Sie einen Text ein:");
    String text = Console.in.readLine();
    boolean palindrom = true;
    for (int i = 0; (i<text.length()/2 && palindrom);i++) {
      palindrom = 
      (text.charAt(i)==text.charAt(text.length()-(i + 1)));
      //Die nachfolgende Zeile dient dazu, den Algorithmus 
      //zu verdeutlichen. Man beachte auch die Bedingung 
      //in der for-Schleife
      System.out.println(text.charAt(i) + " " +
                       text.charAt(text.length() - (i + 1))
                       + " " + palindrom);
    }
    String ausgabe = palindrom?"Palindrom":"kein Palindrom";
    System.out.println(ausgabe);
  }
}
  Bei der Generierung der Ausgabe in der vorletzten Zeile wird der tenäre Operator '_?_ :_' benutzt. Er arbeitet so: Vor dem Fragezeichen steht ein Ausdruck der zu true oder false ausgewertet wird. Hinter dem Fragezeichen stehen zwei Ausdrücke, deren Werte vom gleichen Typ sein müssen. Zusätzlich muss dieser Typ so sein, dass der Wert zu dem Typ vor dem Gleichheitszeichen passt. Wird nun der Ausdruck vor dem Fragezeichen zu true ausgewertet, dann wird der Wert vor dem Doppelpunkt der Variablen zugewiesen, andernfalls der Wert nach dem Doppelpunkt. Konkret heißt das, hat die boolesche Variable palindrom den Wert true, dann wird das String - Objekt mit "Palindrom" andernfalls mit "kein Palindrom" belegt.
 
Ausgabe Geben Sie einen Text zum testen ein:
abcddcba
a a true
b b true
c c true
d d true
Palindrom

Geben Sie einen Text zum testen ein:
abcddgba
a a true
b b true
c g false
kein Palindrom
 

Aufgabe 4 Die Ausgaben des ersten  Programms sind:

false
true

      String text1 = new String("Java");
      String text2 = new String("Java");

Der Kompiler erkennt zwar, dass beide Stringinhalte gleich
legt aber zwei verschiedene Referenzen an, da dies durch das explizite Aufrufen des Konstruktors so gefordert wird. Die Abfrage nach der Gleichheit der Referenzen wird dann mit false verneint.

Die Ausgaben des zweiten Programms sind:

true
true

      String text1 = "Java";
      String text2 = "Java";

Der Kompiler erkennt wieder die Gleichheit der Inhalte. Da nun nicht mehr explizit die Erzeugung zweier String-Objekte verlangt wird, führt Java eine Speicheroptimierung durch, die sich darin zeigt, dass text2 auf die gleiche Referenz verweist wie text1.
 

zu 6.11 Type-Casting
6.11.1 Implizites Casten
zur Startseite www.pohlig.de  (C) MPohlig 2007