Grundlagen

Implementieren Sie alle Aufgaben in den dafür vorgesehenen Dateien im Ordner "impl".

  • Bitte lesen Sie die Angabe komplett durch, bevor Sie mit der Umsetzung beginnen.
  • Halten Sie sich genau an die Angabe und geben Sie nur die geforderten Daten aus.
  • Haben Sie Schwierigkeiten bei der Umsetzung einer der Teilaufgaben, versuchen Sie andere Teile zuerst umzusetzen und wenden Sie sich zuletzt nochmal der ungelösten Teilaufgabe zu. Sie erhalten auch Punkte für nicht vollständig implementierte Teilaufgaben

Laden Sie die Dateien für diesen Test herunter und entpacken Sie die Dateien mit "jar -xvf charsequence.jar".

Programmieraufgabe

(24 Punkte)

Das Programm CharSequence verarbeitet Zeichenfolgen, die in einem char-Array abgelegt sind. Es stellt dabei einige Operationen zur Manipulation der Zeichenfolge zur Verfügung.

Aufgabenstellung

Die zu implementierenden Teile des Programms umfassen das Verarbeiten der Eingabe in der main-Methode sowie weitere drei Teilaufgaben. Alle zu implementierenden Aufgaben gehören zur ausführbaren Klasse CharSequence.

Einlesen der Befehle

In der main-Methode der Klasse CharSequence wird von der Standardeingabe (System.in) mittels Scanner eingelesen und die Eingabe in einem Array gespeichert.

Das Programm erwartet dann bis zum Ende der Eingabe (EOF durch Ctrl+D) beliebig viele der folgenden Befehle:

  • print gibt den Inhalt des Arrays aus. Der Code zum Einlesen und Verarbeiten dieses Befehls ist bereits vorgegeben und muss von Ihnen nicht modifiziert werden.
  • repeat c l erstellt eine neue Zeichenfolge, bestehend aus dem Zeichen c mit der Länge l und ersetzt die bisherige Zeichefolge durch diese neue Zeichenfolge.
  • replace i j s ersetzt innerhalb der Zeichenfolge den Bereich zwischen i und j mit einer anderen Zeichenfolge s.
  • decode dekodiert die Zeichenfolge und erzeugt eine unkodierte neue Zeichenfolge.

Die angeführten Befehle sollen die zu implementierenden Methoden repeat, replace und decode nutzen.

Hinweis: Sie können davon ausgehen, dass alle Eingaben korrekt sind. Sie brauchen also die einzulesenden Befehle und Werte nicht auf Gültigkeit zu überprüfen und keine Fehlerbehandlung implementieren.

Ausgabe

Der Befehl print erzeugt unmittelbar eine Ausgabe am Bildschirm, hingegen führen die Befehle repeat, replace und decode Modifikationen an der Zeeichenfolge durch. Die Wirkung kann durch anschließende Eingabe von print Überprüft werden.

Gefragte Methoden

public static char[] repeat(char ch, int length)

Diese Funktion erzeugt ein neues Array mit der Länge length, dass ausschließlich mit dem Zeichen ch befüllt ist.

public static char[] replace(char[] arr, int beginIndex, int endIndex, char[] from)

In der spezifizierten Zeichenfolge des Array arr wird ein bestimmter Bereich durch die Zeichenfolge des Arrays from ersetzt. Der Bereich im arr umfasst die Zeichen mit den Indizes beginIndex(inklusive) bis endIndex (exklusive, d.h. die Position endIndex ist nicht mehr inkludiert). Der Fall arr oder from gleich null muss nicht beachtet werden.Hinweis: Die Größe des Quellarrays ist im Allgemeinen nicht gleich der Größe des zu ersetzenden Bereichs, weshalb die Größe des Ergebnissarrays von der Größe von arr abweichen kann. Die Methode soll keine Veränderung in arr selbst bewirken.

Achtung: Diese Methode soll ohne Aufruf von Methoden aus java.util.Arrays oder Systems.arraycopy und ohne Verwendung der Datentypen String, StringBuffer oder StringBuilder programmiert werden.
public static char[] decode(char[] arr)

Diese Funktion dekodiert die Zeichenfolge anhand eines bestehenden Musters. Die kodierte Zeichenfolge enthält abwechselnd eine Ziffer gefolgt von einem Zeichen (beginnend mit einer Ziffer). Die Ziffer gibt jeweils die Anzahl der Wiederholungen des Zeichens an.

Hinweis: Vermeiden Sie doppelten Code und verwenden Sie bei Bedarf bereits bestehende Methoden. Zur Umwandlung einer Ziffer ('0' ... '9') in den entsprechenden int-Wert kann die vorgegebene Methode char2int benutzt werden. Achtung: Diese Methode soll ohne Aufruf von Methoden aus java.util.Arrays oder Systems.arraycopy und ohne Verwendung der Datentypen String, StringBuffer oder StringBuilder programmiert werden.

Herangehensweise

Folgende Vorgehensweise ist bei der Umsetzung der Aufgabe empfehlenswert:

  • Beginnen Sie mit der Implementierung der Methode repeat.
  • Implementieren Sie anschließend die Methode replace.
  • Implementieren Sie erst am Ende die Methode decode.
  • Implementieren Sie jeweils parallel dazu die main-Methode, um die fertiggestellten Methoden testen zu können.

Theoriefragen

Halten Sie Ihre Antworten kurz und beschränken Sie sich auf das Wesentliche.

1. Frage:

(3 Punkte)

Betrachten Sie folgendes Programmstück und prüfen Sie, ob sich die Methode append gemäß der im Kommentar angegebenen Spezifikation verhält.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static void main(String[] args) {
 
    char[] u = new char[] {'a', 'b', 'c'};
     
    char[] v = u;
    u[1] = 'c';
    append(u, 'x');
 
    System.out.println(Arrays.toString(v));
 
}
 
 
/**
 * Hängt ein neues Zeichen an das angegebene Array an.
 * Das Array wird dabei um eine Stelle größer.
 * @param zeichenkette ein Array mit Zeichen.
 * @param das neue Zeichen, das angehängt wird.
 */
public static void append(char[] zeichenkette, char zeichen) {
 
    char[] a = new char[zeichenkette.length + 1];
 
    for (int i = 0; i < zeichenkette.length; i++) {
            a[i] = zeichenkette[i];
    }
 
    zeichenkette = a;
    zeichenkette[zeichenkette.length-1] = zeichen;
 
}

  • Welche Ausgabe erzeugt dieses Programm?
    ['a', 'b', 'c']
    ['x', 'c', 'c']
    ['a', 'b', 'x']
    ['x', 'b', 'c']
    ['a', 'b', 'c', 'x']
    ['a', 'c', 'c', 'x']
    ['a', 'c', 'c']
    ['a', 'x', 'c']
    (1 Teilpunkt)
  • Warum wird diese Ausgabe erzeugt? Insgesamt können keine, eine oder mehrere Erklärungen richtig sein:
    Weil u und v nicht dasselbe Array referenzieren.
    Weil append eine Methode mit Seiteneffekten ist.
    Weil zeichenkette ein Variablenparameter ist und sich die Zuweisung zeichenkette = a; im Methodenrumpf daher auch auf den aktuellen Parameter u auswirkt.
    Weil sich die Zuweisung zeichenkette[zeichenkette.length-1] = zeichen; nicht auf den aktuellen Parameter u auswirkt.
    (2 Teilpunkte)

2. Frage:

(3 Punkte)

Betrachten Sie folgende Methode:

1
2
3
4
5
6
7
8
9
10
11
12
// Vorbedingungen: a, b > 0
public static int foo(int a, int b) {
         
    int result = 1;
     
    for(; a>=1; --a) {
        result *= b;   
    }
     
    return result;
                 
}

  • Welche arithmetische Operation wird durch foo berechnet?
    foo(a, b) ==
    Math.pow(b, a)
    Math.pow(2, a)
    Math.pow(a, b)
    b - a
    a + b
    b / a
    a / b
    (1 Teilpunkt)
  • Die Methode kann leicht so verändert werden, dass gilt foo(a, b) == a * b. Welche Änderungen sind dafür erforderlich, damit also die Methode foo unter den genannten Vorbedingungen den Wert von a*b berechnet. (Die Berechnung soll weiterhin durch eine Schleife erfolgen. Geben Sie hier eine Änderung an die möglichst wenige Zeichen betrifft.)
    (2 Teilpunkte)

Testfälle

Kompilieren Sie früh und oft und versuchen Sie Fehler sofort zu beheben. Testen Sie nach jedem Kompilieren Ihre Implementierung. Zum Testen Ihrer Implementierung können Sie die mitgelieferten Ein- und Ausgabe-Paare im Ordner io nutzen. Rufen Sie Ihr Programm (z.B. für spec.$1) wie folgt auf:
java CharSequence < ../io/spec.i1

Vergleichen Sie die Ausgabe des Programms anschließend mit der geforderten Ausgabe in den entsprechenden Dateien (z.B.: spec.o1). Wenn Sie direkt auf der Konsole Eingaben vornehmen, beenden Sie die Eingabe mit Strg+D.

spec.$1

INPUT

blahblah
repeat e 5
print

OUTPUT

[e, e, e, e, e]

spec.$2

INPUT

blahblah
print
replace 4 4 ***
print
replace 4 7 xyz
print

OUTPUT

[b, l, a, h, b, l, a, h]
[b, l, a, h, *, *, *, b, l, a, h]
[b, l, a, h, x, y, z, b, l, a, h]

spec.$3

INPUT

3a4b5c
decode
print

OUTPUT

[a, a, a, b, b, b, b, c, c, c, c, c]

spec.$4

INPUT

3g7f1g
decode
print

OUTPUT

[g, g, g, f, f, f, f, f, f, f, g]
Dies ist eine Demo, die Daten werden nicht gespeichert und sind daher nach einem Reload der Seite verschwunden!