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.
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
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.arr
wird ein bestimmter Bereich durch die Zeichenfolge des Arraysfrom
ersetzt. Der Bereich imarr
umfasst die Zeichen mit den IndizesbeginIndex
(inklusive) bisendIndex
(exklusive, d.h. die PositionendIndex
ist nicht mehr inkludiert). Der Fallarr
oderfrom
gleichnull
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 vonarr
abweichen kann. Die Methode soll keine Veränderung inarr
selbst bewirken.
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 entsprechendenint
-Wert kann die vorgegebene Methodechar2int
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'] -
Warum wird diese Ausgabe erzeugt? Insgesamt können keine, eine oder mehrere Erklärungen richtig sein:
Weil u
undv
nicht dasselbe Array referenzieren.Weil append
eine Methode mit Seiteneffekten ist.Weil zeichenkette
ein Variablenparameter ist und sich die Zuweisungzeichenkette = a;
im Methodenrumpf daher auch auf den aktuellen Parameteru
auswirkt.Weil sich die Zuweisung zeichenkette[zeichenkette.length-1] = zeichen;
nicht auf den aktuellen Parameteru
auswirkt.
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 - Die Methode kann leicht so verändert werden, dass gilt
foo(a, b) == a * b
. Welche Änderungen sind dafür erforderlich, damit also die Methodefoo
unter den genannten Vorbedingungen den Wert vona*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]