Montag, 6. Juni 2011

 

Listings - Source Code drucken

Es sollte m.E. doch möglich sein, Listings in der folgenden - lesbaren - Form zu erzeugen:
Die Schrift ist leserlich, die Zeilen richtig eingerückt, Dateiname und Autor etc. sind ersichtlich (Ich gebe zu, dieses Bild ist schlecht...). Verwendet wurde recode und a2ps unter Linux. 
Wichtig ist auch, dass man allgemeine Programmierrichtlinien befolgt.
Aber mit Office kann man auch sehr schöne Listings erzeugen:
Man muss nur Kopf- und Fußzeilen einrichten, die Schrift auf Courier New (9 oder 10pt) oder eine andere mit fixer Breite und dann zwei Seiten auf eine drucken.
Ähnliches gibt es schon unter Listings (Source-Code drucken) zu lesen.

Stattdessen bekommt man so etwas.

Der Sourcecode ist unmöglich zu lesen, weil die Einrückung bald die dargestellte Zeilenlänge erreicht. Die Schriftgröße ist aber zumindest OK.

Schlimm ist aber das folgende Listing, da würden 4 Code-Seiten auf einem Blatt Platz haben. Trotzdem sind es aber nur 2 Seiten pro Blatt. Die Schrift ist unleserlich klein.

Das ist eine Zumutung!

Labels: , , , , ,


Mittwoch, 2. Juni 2010

 

Literaturverwaltung - RandomAccessFile

Jemand will Zeitschriftenartikel, Bücher und Internet-Links für seine Recherchen verwalten. Schreiben Sie dazu eine Java-Klasse (plus eventuelle Hilfsklassen), welche es ermöglicht diese Daten in einer RandomAccess-Datei zu speichern. Folgende Daten sollen in der Klasse Eintrag erfasst werden:
  1. autor - String(100)
  2. titel - String(100)
  3. erscheinungsjahr - int
  4. verlag - String(30)
  5. zeitschrift - String(30)
  6. seiten - String(10)
  7. link - String(60)
String(100) bedeutet, dass dafür maximal 100 (genau 100) Zeichen gespeichert werden soll. Sie können das so implementieren, dass kürzere Strings hinten mit Leerzeichen gefüllt werden. Längere Strings müssen abgeschnitten werden. Für eine eventuelle Anzeige/Ausgabe müssen aber die Füllzeichen entfernt werden. Die Klasse Eintrag ist mit entsprechenden Getter- und Setter-Methoden auszustatten (die bei den Strings das Abschneiden und Auffüllen bewerkstelligen).

Die Klasse Literatur für die Verwaltung der Datensätze soll folgende Methoden bereitstellen:
Der Konstruktor der Klasse Literatur soll eine geöffnete RandomAccess-Datei als Parameter haben:
public Literatur(RandomAccessFile file)

Implementieren Sie das Löschen so, dass der jeweilige Eintrag als gelöscht markiert wird (zusätzliches Feld) und diese Änderung in der Datei gespeichert wird. Der Datensatz ist also physisch noch in der Datei. Bei der Methode lese() muss also im Falle eines gelöschten Eintrags null geliefert werden.
Umgekehrt muss bei neuerEintrag() zunächst ein gelöschter Eintrag gesucht werden. Wird ein solcher gefunden, so wird er durch den neuen ersetzt (Lösch-Markierung muss wieder zurückgesetzt werden). Wird kein gelöschter Datensatz gefunden, so ist der neue an die Datei anzuhängen.

Schreiben Sie ein kleines Testprogramm zum Testen Ihrer Klassen.

Anmerkung: Die Daten sind für eine echte Anwendung nicht ausreichend und müssten unterteilt werden, da es z.B. mehrere Autoren für einen Artikel gibt.

Hinweishier finden Sie eine Testklasse zum Testen der Klasse Literatur. Die Klasse Literatur muss wie diese Testklasse im Package literatur sein. Weiters muss die Library für JUnit 3 angegeben werden. Diese Testklasse trifft gewissen Annahmen zur Implementierung von Literatur und Eintrag. Bitte passen Sie entweder die Testklasse an Ihre Implementierung an oder Sie ändern Ihre Literatur bzw. Eintrag-Klassen entsprechend (z.B. nimmt der Test an, dass es eine read() und eine write()-Methode gibt, die einen Datensatz ("in sich hinein") liest bzw. einen Datensatz ("sich selbst") schreibt (jeweils an die Position, die in Literatur bestimmt wurde).

Ihre Klasse Eintrag könnte etwa so beginnen:
public class Eintrag {

  // Feldlängen
  private final static int autorLen = 100;
  private final static int titelLen = 100;
  private final static int verlagLen = 30;
  private final static int zeitschriftLen = 30;
  private final static int seitenLen = 10;
  private final static int linkLen = 60;

  // Felder
  private String autor;
  private String titel;
  private int erscheinungsjahr;
  private String verlag;
  private String zeitschrift;
  private String seiten;
  private String link;

  // gelöscht?
  private boolean istGeloescht = false;
Da eine fixe Datensatzlänge gefordert ist, müssen Sie die Länge ermitteln, indem Sie die Längen der einzelnen Felder zusammenzählen. Wir schätzen für Boolean die Länge von int (bestimmt mit Hilfe der Wrapperklasse Integer und der Konstante SIZE, welche die Länge in Bits angibt).
public static int eintragLen() {
    int len = Integer.SIZE
        / 8
        + (autorLen + titelLen + verlagLen + zeitschriftLen + seitenLen + linkLen)
        * 3 + 6 * Long.SIZE / 8 + Integer.SIZE / 8;
    return len;
  }
Der Faktor 3 entsteht durch die Verwendung der UTF-8-Kodierung. UTF-8 ist eine Kodierung des Unicodes und speichert alle Zeichen des ASCII-Codes auch in der selben Kodierung wie ASCII, daher werden dann für andere Zeichen 2, 3 bzw. 4 Bytes verwendet (Unicode verwendete in den ersteren Versionen 16 Bit, in Java werden daher Zeichen mit 16 Bit kodiert). Um ganz sicher zu sein, müsste man den Faktor 4 verwenden. Long.SIZE / 8 ist die Längeninformation, die in jedem String-Objekt gespeichert ist.
Strings werden mit file.writeUTF(string); geschrieben bzw. mit string = file.readUTF(); gelesen.
public void write(RandomAccessFile out) throws IOException {
    out.writeBoolean(istGeloescht);
    out.writeUTF(autor);
    out.writeUTF(link);
    out.writeUTF(seiten);
    out.writeUTF(titel);
    out.writeUTF(verlag);
    out.writeUTF(zeitschrift);
    out.writeInt(erscheinungsjahr);
  }

  public void read(RandomAccessFile in) throws IOException, EOFException {
    istGeloescht = in.readBoolean();
    autor = in.readUTF();
    link = in.readUTF();
    seiten = in.readUTF();
    titel = in.readUTF();
    verlag = in.readUTF();
    zeitschrift = in.readUTF();
    erscheinungsjahr = in.readInt();
  }
Die String-Felder müssen natürlich auf eine fixe Länge gebracht werden, d.h. zu lange Strings müssen abgeschnitten, zu kurze evtl. verlängert werden. Dies erledigt man am Besten in den Setter- bzw. Getter-Methoden.
Das Lesen eines Datensatzes in der Klasse Literatur könnte etwa so funktionieren:
public Eintrag lese(int nummer) throws IOException {
    long pos = nummer * Eintrag.eintragLen();
    if (pos < file.length()) {
      file.seek(pos);
      Eintrag eintrag = new Eintrag();
      eintrag.read(file);
      if (!eintrag.istGeloescht()) {
        return eintrag;
      } else {
        return null; // gelöschter Eintrag gilt als nicht vorhanden
      }
    } else {
      return null; // über die Dateilänge hinaus
    }
  }
Vervollständigen Sie mit diesen Informationen Ihre Klassen.
Nennen Sie das Projekt klasse-literatur-name (klasse ... 2ad, 2bd, 2cd, name ... Ihr Familienname), z.B. 2ad-literatur-haberstroh.

Labels: , ,


Mittwoch, 26. Mai 2010

 

Beispielprojekt zu binären Bäumen

Die Datei java-baum_1_1.zip enthält ein Eclipse-Projekt (Importieren wie hier beschrieben) zu binären Bäumen.
Das Paket simple enthält einen einfachen Baum mit Einfügemethode sowie ein paar Methoden zur Bestimmung der Höhe (Tiefe) des Baumes, der Anzahl der Knoten und der Suche im Baum. Teilweise gibt es rekursive und nichtrekursive Varianten der Methoden (soweit möglich).
Das Paket wortbaum enthält ein Beispiel zur Ermittlung von Worthäufigkeiten.
Das Paket xref enthält eine Musterlösung zur Aufgabe XRef (Cross Referenz).

Labels: , , ,


 

Beispielprojekt zu Java-Collections, Import von Projekten in Eclipse

Die Datei java-collections_1_1.zip enthält ein Eclipse-Projekt mit einem Beispiel zur Verwendung der Java-Collection-API.
Im Package simple finden Sie ein Beispiel zur Ermittlung der Worthäufigkeiten wobei im main nur ein Aufruf mit fixen Testdaten (Array) vorhanden ist.
Das Package step1 zeigt die Vorarbeiten zu dem Programm hauf mit einer eigenen Datenstruktur Data, in der ein Wort und die Häufigkeit gespeichert wird. Zusätzlich implementiert Data das Interface Comparable um eine natürliche Sortierung nach dem Wort zu ermöglichen. Das Interface Comparator wird implementiert, um nach Häufigkeiten zu sortieren. Um auch nach Häufigkeiten absteigend zu sortieren, enthält die Datei Data.java noch eine Klasse DataHaufUmgekehrt, welche ebenfalls Comparator implementiert.
Im folgenden der Ausschnitt mit dem main, welches zeigt, wie man sortiert:
public static void main(String[] args) {
    Data[] worte = new Data[] { new Data("das", 12), new Data("Haus", 3),
        new Data("Text", 23), new Data("Punkt", 2), new Data("Testdaten", 12) };
    System.out.println("unsortiert");
    for (Data d : worte) {
      System.out.println("  " + d);
    }
    Arrays.sort(worte);
    System.out.println("sortiert nach Wort");
    for (Data d : worte) {
      System.out.println("  " + d);
    }
    Arrays.sort(worte, new Data());
    System.out.println("sortiert nach Anzahl");
    for (Data d : worte) {
      System.out.println("  " + d);
    }

    Arrays.sort(worte, new DataHaufUmgekehrt());
    System.out.println("sortiert nach Anzahl absteigend");
    for (Data d : worte) {
      System.out.println("  " + d);
    }
  }

Im Paket step2 wird dann das Beispiel ausgebaut, sodass in der Klasse Hauf zwei Varianten von Maps zum Speichern der Worthäufigkeiten verwendet werden. Eine HashMap und eine TreeMap. Für die HashMap muss die Klasse Data zusätzlich noch die Methoden equals() und hashCode() implementieren (überschreiben).
Im main von Hauf werden dann Worte aus der Standardeingabe gelesen und in den zwei Maps gespeichert.

Die Datei java-collections_1_1.zip kann nach dem Download direkt in Eclipse importiert werden:
Man wählt dann die Datei aus:
Man erhält dann folgendes Projekt:

Labels: , ,


Mittwoch, 21. April 2010

 

Xref (Cross Referenz)

Erstellen Sie ein Java-Program, welches für jedes gelesene Wort bestimmt, in welchen Zeilen es vorkommt.
Gegeben sei folgende Eingabe:

Das ist die erste Zeile und
das ist die zweite Zeile und
hier folgt die dritte Zeile.
Satzzeichen gelten als Trenner.
Folgendes ist kein W0rt und das
4uch nicht.

Das Programm soll dann diese Ausgabe liefern.
als (1): 4
Das (3): 1, 2, 5
die (3): 1, 2, 3
dritte (1): 3
erste (1): 1
Folgendes (1): 5
folgt (1): 3
gelten (1): 4
hier (1): 3
ist (3): 1, 2, 5
kein (1): 5
nicht (1): 6
Satzzeichen (1): 4
Trenner (1): 4
und (3): 1, 2, 5
Zeile (3): 1, 2, 3
zweite (1): 2

Es erzeugt also eine Liste von Worten (in der zuerst vorkommenden Schreibweise), mit der Anzahl der Vorkommnisse in Klammern und dann einer Liste von Zeilennummern.

Verwenden Sie dazu einen binären Baum für die Wörter und Listen für die Zeilennummern. Das bedeutet, dass wir einen Baum haben bei dem jeder Knoten eine Liste von Zeilennummern "enthält".


Das Programm soll von der Standardeingabe oder von beliebig vielen Dateien lesen.
Zur Erkennung von Wörtern lesen Sie hier: Wörter in der Eingabe erkennen


Nennen Sie das Projekt xref (also z.B. 2ad-maierhofer-java-xref) und geben Sie am CVS ab.

Labels: , ,


 

Binäre Bäume - Suchen von Namen und/oder Telefonnummern


Immer wieder will man nicht nur die Telefonnummer zu einem Namen suchen sondern auch umgekehrt zu einer Telefonnummer den Namen. Folgendes Programm hilft:
Erstellen Sie ein Programm Telefonsuche.java, welches aus einer (oder mehreren) Datei(en) Telefondaten einliest (Name, Vorname, Telefonnummer - entsprechende Klasse) und in zwei Bäume einträgt. Ein Baum sortiert nach Name, der zweite sortiert nach Telefonnummer. Dabei gibt es grundsätzlich zwei Möglichkeiten:
- die Klasse hat jeweils zwei Paare von Nachfolgern, für jede Sortierung
- die Klasse hat nur ein Paar von Nachfolgern, eine Kopie wird im zweiten Baum eingetragen
Das Programm soll dann einfach einen String einlesen und zunächst im Namenbaumsuchen. Kommt der String nicht vor, so ist dann im Nummernbaum zu suchen.
Wie kann man nur nach Teilen des Namens bzw. der Nummer suchen?
Nennen Sie das Projekt telefonsuche, also z.B. 2ad-maierhofer-java-telefonsuche.

Labels: , ,


 

Worthäufigkeiten mit binärem Baum ermitteln

Erstellen Sie ein Java-Programm welches für jedes gelesene Wort bestimmt, wie oft es vorkommt. Nach dem Ende der Eingabe (EOF) ist eine Liste von Worten und deren Häufigkeiten auszugeben.
Ein Beispiel, gegeben sei folgende Eingabe:

Das ist die erste Zeile und
das ist die zweite Zeile und
hier folgt die dritte Zeile.
Satzzeichen gelten als Trenner.
Folgendes ist kein W0rt und das
4uch nicht.

Das Programm soll dann diese Ausgabe liefern.

als 1
Das 3
die 3
dritte 1
erste 1
Folgendes 1
folgt 1
gelten 1
hier 1
ist 3
kein 1
nicht 1
Satzzeichen 1
Trenner 1
und 3
Zeile 3
zweite 1

Es erzeugt also eine Liste von Worten (in der zuerst vorkommenden Schreibweise), mit der Anzahl der Vorkommnisse.
Das Programm soll von der Standardeingabe oder von beliebig vielen Dateien lesen.
Zur Erkennung von Wörtern lesen Sie hier: Wörter in der Eingabe erkennen

Verwenden Sie dazu einen binären Baum für die Wörter.
Nennen Sie das Projekt hauf (also z.B. 2ad-maierhofer-java-hauf) und geben Sie am CVS ab.

Labels: , ,


Mittwoch, 7. April 2010

 

Aufgabe Verkettete Listen - Partner finden für Tanzkurs

Teilnehmerinnen und Teilnehmer melden sich zu einem Tanzkurs an. Der Tanzlehrer stellt die Paare zusammen, indem er immer eine Frau aus der Liste der Teilnehmerinnen und einen Mann aus der Liste der Teilnehmer nimmt (und streicht).

Eine Liste wird immer vollständig leer werden, die zweite kann noch TeilnehmerInnen enthalten.

Aufgabenstellung mit verketteten Listen


Erstellen Sie ein Programm, welches zwei Dateien, in denen die Namen sind, liest und die Namen in die entsprechende Liste (alphabetisch sortiert) einfügt.

Die Zusammenstellung der Paare erfolgt dann so, dass jeweils ein (zufälliges) Element aus der ersten Liste und ein (zufälliges) Element aus der zweiten Liste entfernt. Im einfacheren Fall wird das Paar einfach ausgegeben und die beiden Listenelemente freigegeben (alle Referenzen auf die Listenelemente auf null setzen, sodass der Garbage Collector den Speicher freigeben kann). In der fortgeschrittenen Lösung wird das Paar in eine spezielle Liste übernommen, deren Elemente jeweils Referenzen auf die beiden Teilnehmer enthält. Zum Schluss wird diese Liste ausgegeben.

Mögliche Datenstrukturen


class Teilnehmer {
   Teilnehmer next;
   String name;
}
An geeigneter Stelle sollte es etwas wie folgt geben:
Teilnehmer frauen = null;
Teilnehmer maenner = null;

Für Paare wird es eine eigene Datenstruktur (Klasse) geben:
class Paar {
   Paar next;
   Teilnehmer frau;
   Teilnehmer mann;
}
An geeigneter Stelle sollte es etwas wie folgt geben:
Paar paare = null;

Gesamtprogramm und Tests


Aufrufbeispiel bei zufälliger Auswahl der Tanzpartner:
hp@l211 $ java TanzkursListe male female
6  Paare
========

       Felix <-> Petra
       Franz <-> Sonja
      Harald <-> Elke
      Martin <-> Gabi
       Peter <-> Karin
    Reinhold <-> Brigitte

Übriggebliebene
===============

Andrea

Dabei enthält die Datei male die Namen der Männer und female die Namen der Frauen:
male
Harald
Franz
Martin
Felix
Peter
Reinhold
female
Gabi
Elke
Sonja
Brigitte
Karin
Petra
Andrea

Nach dem Einlesen der Dateien sollten zwei Listen, etwa wie im Bild skizziert, enstehen:

Die Zuordnung der Paare erzeugt eine Liste wie folgt. Eine Dame bleibt bei in der Liste frauen:

Labels: , ,


Mittwoch, 24. März 2010

 

Aufgaben zu Verketteten Listen

Diese Aufgabe enthält mehrere Übungsbeispiele zu Listen. Es sollen verschiedenste Aufgabenstellungen mit verketteten Listen gelöst werden, um das Verständnis mit Beispielen zu vertiefen.
Welche Daten in den Listen gespeichert werden ist meist nicht so wichtig. Verwenden Sie Strings oder ganze Zahlen, wenn nichts anderes angegeben wird.
Erstellen Sie jeweils eine Klasse public class Liste, wie in Verkettete Listen beschrieben mit den in der jeweiligen Aufgabenstellung geforderten Methoden. Für die Datenelemente erzeugen Sie eine Klasse public class Data, welche einen ganzzahligen Wert (int key) und einen String (String value) aufnehmen kann.

1. Am Ende einer (einfach verketteten) Liste einfügen und löschen.

Schreiben Sie die Funktionen
void append(Data data);   /* anhängen */
void delEnd();            /* entfernen des letzten Elements */
Skizzieren Sie mehrere Listenbeispiele und entwickeln sie passende Testfälle (leere Liste, ein Element, 2 Elemente, 3 oder mehr Elemente).

2. Sortiertes Einfügen in eine doppelt verkettete Liste

Schreiben Sie eine Funktion
void insert_sort(Data data);
welche ein Element sortiert nach key in die doppelt verkettete Liste einfügt (Vorwärts- und Rückwärtsverkettung).

3. Löschen eines bestimmten Elements

Schreiben Sie eine Funktion
boolean del(Data data);
welche ein Element mit dem gesuchten Inhalt löscht (meist wird nur ein key verwendet, hier können Sie aber einfach die Daten verwenden). del() soll true liefern, wenn das Element gefunden und gelöscht wurde.

4. Ändern eines Elements in einer einfach verketteten Liste

Schreiben Sie eine Funktion
void change(Data old, Data newdata);
welche ein Element old aus der Liste nimmt, es durch die Werte von newdata ersetzt und dieses Element dann wieder an geeigneter Stelle einfügt, sodass die Liste nach diesem Aufruf wieder sortiert ist (normalerweise betrifft das Enfernen und Wiedereinfügen nur denkey).
Erstellen Sie für alle Funktionen passende Testfälle und fertigen Sie ggf. Skizzen an.

5. Sortiertes Einfügen

Erstellen Sie ein Java-Programm, welches Namen von der Standardeingabe liest und sortiert in eine einfach verkettete Liste einträgt. Bei EOF wird dann die Liste auf der Standardausgabe ausgegeben.

Machen Sie zwei Varianten:

  1. Iteratives sortiertes Einfügen und iteratves Ausgeben
  2. Rekursives sortieres Einfügen und rekursives Ausgeben

Labels: , ,


Mittwoch, 10. März 2010

 

Verkettete Listen

Folgendes Bild stellt das Prinzip der verketteten Listen dar. Wir benötigen einen Anker (pAnker), der auf das erste Element "zeigt". Jedes Element "zeigt" auf einen Nachfolger. Nur das letzte Element hat keinen Nachfolger und enthält daher null.

In Java könnte das etwa so formuliert werden:

class Element {
Element next;
int data;
Element(int data) {
this.data = data;
}
}

Element anker = null; // leere Liste

Element n = new Element(1);
n.next = anker;
anker = n;

n = new Element(2);
n.next = anker;
anker = n;

n = new Element(3);
n.next = anker;
anker = n;

System.out.println("liste");
for (Element e = anker; e != null; e = e.next) {
System.out.println(e.data);
}

// 1. Element entfernen
anker = anker.next;
System.out.println("liste");
for (Element e = anker; e != null; e = e.next) {
System.out.println(e.data);
}


Folgendes Listing zeigt eine mögliche Implementierung einer einfach verketteten Liste sowie die Verwendung einer solchen Liste als Stack. Neue Elemente werden einfach vorne eingefügt:

public class Liste {

private class Element {
Element next;
int data;

Element(int data) {
this.data = data;
}
}

private Element anker = null;

// private Element ende = null;

public void append(int data) {
if (anker == null) {
anker = new Element(data);
} else {
// suche Ende
Element e = anker;
while (e.next != null) {
e = e.next;
}
// e ist das letzte Element (Ende)
e.next = new Element(data);
}
}

public void insertFirst(int data) {
Element n = new Element(data);
n.next = anker;
anker = n;
}

public void deleteFirst() {
assert (anker != null);
anker = anker.next;
}

public void printList() {
System.out.print("[");
for (Element e = anker; e != null; e = e.next) {
System.out.print(e.data + " ");
}
System.out.println("]");
}

public void push(int data) {
insertFirst(data);
}

public int pop() {
assert (anker != null);
Element e = anker;
anker = anker.next;
return e.data;
}

public boolean isEmpty() {
return anker == null;
}

/**
* @param args
*/
public static void main(String[] args) {
Liste liste = new Liste();
liste.printList();
// liste.insertFirst(1);
// liste.insertFirst(2);
// liste.insertFirst(3);
liste.append(1);
liste.append(2);
liste.append(3);
liste.printList();
liste.deleteFirst();
liste.printList();

Liste stack = new Liste();
stack.push(23);
stack.push(3);
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}

}

Da bei obigem Beispiel in der Methode append() immer das Ende der Liste gesucht wird, ist das Anhängen von Elementen etwas aufwändig, vor allem, wenn die Liste schon länger ist. Dies kann man verbessern, indem man auch das Ende der Liste mitspeichert.
Es folgt nun eine etwas andere Implementierung von Elementen (Node) und einer Liste (Liste), welche als Stack oder als Queue verwendet werden kann. Hier werden immer Objekte vom Typ Node in der Liste manipuliert.

public class Node {
Node next;
String data;

public Node(String data) {
this.data = data;
}
public Node() {
data = null;
}
public String toString() {
return data;
}
}

Als Daten werden einfach Strings verwendet.

public class Liste {
private Node anker = null;
private Node last = null;

/**
* hängt Knoten n am Ende der Liste an (für Queue).
*
* @param n
* neuer Knoten
*/
public void put(Node n) {
if (last == null) { // erstes Element
anker = n;
last = n;
} else {
last.next = n;
last = n;
}
}

/**
* liefert erstes Element und entfernt dieses aus der Liste
*
* @return erster Knoten oder null
*/
public Node get() {
Node ret = null;
if (anker != null) {
ret = anker;
anker = anker.next;
if (anker == null) { // war das das letzte Element?
last = null;
}
}
return ret;
}

/**
* pop() für Verwendung als Stack.
*
* @return erstes Element
*/
public Node pop() {
return get();
}

/**
* fügt Knoten vorne ein (für Stack).
*
* @param n
* neuer Knoten
*/
public void push(Node n) {
if (anker == null) {
anker = n;
last = anker;
} else {
n.next = anker;
anker = n;
}
}

/**
* liefert Liste als String.
*
* @return "[erstes,zweites,...]", "[]" bei leerer Liste (KEINE Leerzeichen)
*/
public String toString() {
String ret = "[";
Node n;
for (n = anker; n != null && n.next != null; n = n.next) {
ret += n + ",";
}
if (n != null) {
ret += n;
}
ret += "]";
return ret;
}
}

Das Anhängen von Elementen ist hier effizienter gelöst durch die Verwendung von last, einer Referenz auf das letzte Element.

Labels: ,


 

einfache erkennende Automaten, implementiert mit Zustandstabelle

Erstellen Sie jeweils eine Klasse, die einen Automaten zur Erkennung von
imlpementiert. Implementieren Sie die Automaten mit Hilfe einer Zustandstabelle.
Die Automaten sollen jeweils eine Methode

boolean accept(String input)
implementieren, welche true liefert, wenn der Automat den String input akzeptiert.

Beispiele für Telefonnummern:
27871 ... ohne Vorwahl (im Ort), ohne Durchwahl
27871-200 ... ohne Vorwahl mit Durchwahl
02622/27871 ... mit Vorwahl ohne Durchwahl
02622/27871-200 ... mit Vorwahl mit Durchwahl
+432622/27871 ... mit Vorwahl ohne Durchwahl
+432622/27871-200 ... mit Vorwahl mit Durchwahl
+43 2622 / 27 8 71 - 200 ... mit Vorwahl mit Durchwahl und eingestreuten Leerzeichen

Beispiele für Postleitzahlen:
2700, A-2700, D-23790, F-23091

Beispiele für Autokennzeichen:
W123X, L INZ23, WU123A, W 34597A, GFRAST2, GF RAST3
Nach dem Ortskennzeichen (1 bis 2 Buchstaben) darf ein Leerzeichen stehen. Danach kommt eine Reihe von Buchstaben und dann eine Reihe von Ziffern oder zuerst Ziffern und dann Buchstaben. Ungültig wäre z.B. W2BU3.

Labels: , ,


 

einfache erkennende Automaten, implementiert mit switch

Erstellen Sie jeweils eine Klasse, die einen Automaten zur Erkennung von
imlpementiert. Implementieren Sie die Automaten mit Hilfe eines switch-Statements.
Die Automaten sollen jeweils eine Methode

boolean accept(String input)
implementieren, welche true liefert, wenn der Automat den String input akzeptiert.

Beispiele für Telefonnummern:
27871 ... ohne Vorwahl (im Ort), ohne Durchwahl
27871-200 ... ohne Vorwahl mit Durchwahl
02622/27871 ... mit Vorwahl ohne Durchwahl
02622/27871-200 ... mit Vorwahl mit Durchwahl
+432622/27871 ... mit Vorwahl ohne Durchwahl
+432622/27871-200 ... mit Vorwahl mit Durchwahl
+43 2622 / 27 8 71 - 200 ... mit Vorwahl mit Durchwahl und eingestreuten Leerzeichen

Beispiele für Postleitzahlen:
2700, A-2700, D-23790, F-23091

Beispiele für Autokennzeichen:
W123X, L INZ23, WU123A, W 34597A, GFRAST2, GF RAST3
Nach dem Ortskennzeichen (1 bis 2 Buchstaben) darf ein Leerzeichen stehen. Danach kommt eine Reihe von Buchstaben und dann eine Reihe von Ziffern oder zuerst Ziffern und dann Buchstaben. Ungültig wäre z.B. W2BU3.

Labels: , ,


Mittwoch, 24. Februar 2010

 

Automat

Implementieren Sie folgenden (erkennenden) Automaten in Java.
  1. mittels switch-Statement
  2. mittels Zustandsübergangstabelle
Verwenden Sie für die Zustände
  1. Java-Konstante
  2. ein enum
Sie müssen also vier Varianten des Automaten implementieren. Nennen Sie die Automatenklassen Automat11 (switch, Konstante), Automat12 (switch, enum), Automat21 (Tabelle, Konstante) und Automat22 (Tabelle, enum).
Bestimmen Sie 10 gültige Worte (Worte, die der Automat akzeptieren muss) und 10 ungültige Worte.
Erstellen Sie eine Klasse Main (mit der Methode main()), welche 4 Automaten instantiiert und jeden Automaten mit den 20 Worten testet.
Hier ein Fragment aus der Main-Klasse:
public class Main {
// ...
public static void main(String[] args) {
Automat11 automat1 = new Automat11();
Automat12 automat2 = new Automat12();
Automat21 automat3 = new Automat21();
Automat22 automat4 = new Automat22();
//...
String s = "aabaaass";
System.out.printf("automat1(%s) = %s\n", s, automat1.accept(s));
System.out.printf("automat2(%s) = %s\n", s, automat2.accept(s));
//... usw.
}
// ...
}
Nennen Sie das Projekt automat (z.B. 2ad-meier-java-automat) und checken Sie es am CVS ein.

Labels: , ,


Mittwoch, 20. Januar 2010

 

Aufgabe Gruppenwechsel Ski

Schreiben Sie eine Java-Klasse Grw.java, welches aus dem Datenbestand ski.csv die beigelegte Statistik erzeugt.


Ausschnitt csv-Datei ski.csv als Bild

Lesen Sie die csv -Datei zeilenweise und erstellen Sie aus jeder Zeile ein Objekt einer Klasse SkiDaten, die alle notwendigen Attribute (Klasse, Name, Geb.Datum,....) enthält.

Nennen Sie das Projekt grwski (also insgesamt z.B. 2ad-haberstroh-grwski).

Sollte eine neue Sortierung des Sätze notwendig sein, bitte mit OpenOffice Calc oder Excel sortieren. 1-er Kandidaten sortieren bitte mit eigenem Sortprogramm.

INFO: es handelt sich um einen zweistufigen Gruppenwechsel mit den Gruppen

 KLASSE und GESCHL

und einer Gesamtdarstellung des Durchschnitts!
Eine Einführung in den Gruppenwechsel finden Sie in der Datei gruppenwechsel.pdf

Aufruf des Programms:

java Grw [-h | -o ausgabedat] [-d] eingabedatei

Die Option -d bewirkt die Ausgabe der Detailzeilen, ohne -d nur Summenzeilen ausgeben!

Beispiel Statistik:

--------------------------------- --------------------------------
STATISTIK zum Schuelerrennen der HTL am SKIKURS 2006 in OBERTAUERN
------------------------------------------------------------------

AMINGER Georg 0.02
ELIAS Thomas 0.97
GALAVICS Marcus 0.15
GALLAUNER Alexander 0.26
HECHER Markus 0.58
HERMANN Gregor 0.65
KAMPER Raphael 0.55
KRIVOKUCA Milan 7.73
MOSER Christoph 2.34
NEPOLA René 0.14
PRIELER Stefan 0.63
RECHBERGER Christian 3.11
RIEGLER Mario 0.87
SCHNEEBERGER Joerg 1.22
SENN Bernhard 0.65
WIESSNER Maximilian 1.61
ZENZ Markus 2.04

die durchschnittliche Zeitdifferenz bei den MAENNERN betraegt: 1.38

die KLASSE 2AHDV erreichte eine Durchschnittsdifferenz von 1.38 Sekunden


CMUND Katharina 2.81
HARATHER Alice 1.87
KONLECHNER Viktoria 0.39
RIEGER Jennifer 0.63
RINNHOFER Elisabeth 1.65
...........................................................

...........................................................
REICHHART Thomas 0.30
RIEDER Dominik 1.07
SCHERMANN Georg 0.85
STANGL Stefan 1.48
STAUFER Andreas 0.47

die durchschnittliche Zeitdifferenz bei den MAENNERN betraegt: 2.38

die KLASSE 3CHDV erreichte eine Durchschnittsdifferenz von 2.36 Sekunden
************************************************GESAMT-Differenz : 1.93

Achtung: Die obige Ausgabe stellt nur einen Ausschnitt dar (Aufruf mit Option -d) und es wurde die vorletzte Zeile (Hüpfner) gelöscht, da dort extrem abweichende Zeiten vorkommen (die Schülerin ist scheinbar gestürzt). Die Gesamt-Different würde mit dieser Zeile 11,37Sekunden betragen.

Abgabetermin: Donnerstag, 28. Jänner 2010

Labels: , ,


Mittwoch, 13. Januar 2010

 

Ringbuffer Simulation

Sie finden unter ringbuffer.jar eine Simulation eines Ringbuffers (bzw. Queue).


Aufrufen mit
java -jar ringbuffer.jar


Hier noch ein paar Worte zur Implementierung. Die Klasse Queue ist ganz herkömmlich implementiert. Bei einem Über- bzw. Unterlauf wird eine IndexOutOfBoundsException geworfen. Die Felder der Klasse wurden ohne private definiert, damit die Klasse GraphView im selben Paket direkt darauf zugreifen kann (erspart Schreibarbeit...).
package queuegraph;

/**
* Ringbuffer.
*
* @author Harald R. Haberstroh (hp)
*
*/
public class Ringbuffer {
String[] ring;
int usedSize = 0;
int size = 0;
int getIndex = 0;
int putIndex = 0;
final static int DEFAULTSIZE = 12;

public Ringbuffer(int size) {
this.size = size;
ring = new String[this.size];
}

public Ringbuffer() {
this(DEFAULTSIZE);
}

public void put(String c) throws IndexOutOfBoundsException {
usedSize++;
if (usedSize > size) {
throw new IndexOutOfBoundsException("Ringbufferüberlauf");
}
ring[putIndex] = c;
putIndex = (putIndex + 1) % size;
}

public String get() throws IndexOutOfBoundsException {
usedSize--;
if (usedSize < 0) {
throw new IndexOutOfBoundsException("Ringbuffer schon leer");
}
String ret = ring[getIndex];
getIndex = (getIndex + 1) % size;
return ret;
}

public int getSize() {
return size;
}

public boolean isEmpty() {
return usedSize == 0;
}
}

Die Klasse GraphView erweitert ein JPanel und "zeichnet" das Array mit Inhalt. Zusätzlich werden die "Zeiger" getIndex und putIndex durch die Position dargestellt.

Bei einem Über- bzw. Unterlauf wird der Fehler angezeigt und die Funktion "deaktiviert", indem put() und get() immer prüfen, ob error == null (also kein Fehler gesetzt ist).

Das Fenster wird in main() aufgebaut.

package queuegraph;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

/**
* graphische Darstellung eines Ringbuffers.
*
* @author Harald R. Haberstroh (hp)
*
*/
public class GraphView extends JPanel {
private static final long serialVersionUID = -5311802173756493369L;

private Ringbuffer ringbuffer;

private String error;

/**
* Hier wird das Array mit Inhalt, die Indices und und die Ampel gezeichnet.
*
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int maxx = 0; // für Panelgröße
int maxy = 0;
int x = 10;
int y = 10;

// das Array
for (int i = 0, j = ringbuffer.getIndex; i < ringbuffer.usedSize; i++) {
String s = ringbuffer.ring[j];
Rectangle2D box = g.getFontMetrics().getStringBounds(s, 0, s.length(), g);
int hpos = (int) (15.0 - box.getCenterX());
int vpos = (int) (15.0 - box.getCenterY());
g.drawString(s, j * 30 + hpos + 10, y + vpos);
j = (j + 1) % ringbuffer.getSize();
x = j * 30 + 10;
if (x > maxx)
maxx = x;
if (y > maxy)
maxy = y;
}

// die Indices
x = 10;
y = 10;
for (int i = 0; i < ringbuffer.getSize(); i++) {
g.drawRect(x, y, 30, 30);
if (i == ringbuffer.getIndex) {
pfeil(g, x + 15, y + 30, "getIndex");
}
if (i == ringbuffer.putIndex) {
pfeil(g, x + 15, y + 30, "putIndex");
}
x += 30;
if (x > maxx)
maxx = x;
if (y > maxy)
maxy = y;
}

// Panelgröße
maxx += 10;
maxy += 100;
setPreferredSize(new Dimension(maxx, maxy));

// die Ampel
if (!ringbuffer.isEmpty() && ringbuffer.getIndex == ringbuffer.putIndex) {
g.setColor(Color.RED);
g.fillOval(20, maxy - 5, 10, 10);
} else if (!ringbuffer.isEmpty()) {
g.setColor(Color.YELLOW);
g.fillOval(35, maxy - 5, 10, 10);
} else {
g.setColor(Color.GREEN);
g.fillOval(50, maxy - 5, 10, 10);
}
g.setColor(getForeground());
g.drawOval(20, maxy - 5, 10, 10);
g.drawOval(35, maxy - 5, 10, 10);
g.drawOval(50, maxy - 5, 10, 10);
g.drawString("Füllstand", 80, maxy - 5 + g.getFontMetrics().getAscent());

// Fehlermeldung
if (error != null) {
g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 35));
g.setColor(Color.YELLOW);
Rectangle2D box = g.getFontMetrics().getStringBounds(error, 0,
error.length(), g);
g.drawString(error, (int) (getWidth() / 2.0 - box.getCenterX()) + 2,
(int) (getHeight() / 2.0 - box.getCenterY()) - 2);
g.setColor(Color.RED);
g.drawString(error, (int) (getWidth() / 2.0 - box.getCenterX()),
(int) (getHeight() / 2.0 - box.getCenterY()));
}
}

private void pfeil(Graphics g, int x, int y, String bez) {
// FIXME: ist noch kein Pfeil, nur Linie
g.drawLine(x, y, x, y + 30);
Rectangle2D box = g.getFontMetrics().getStringBounds(bez, 0, bez.length(),
g);
int hpos = (int) (x - box.getCenterX());
int vpos = (int) (y + 30 + box.getHeight());
g.drawString(bez, hpos, vpos);
}

public GraphView() {
ringbuffer = new Ringbuffer();
}

public void put(String c) {
if (error != null)
return;
try {
ringbuffer.put(c);
} catch (IndexOutOfBoundsException e) {
error = "Ringbufferüberlauf";
}
repaint();
}

public String get() {
String ret = null;
if (error != null)
return ret;
try {
ret = ringbuffer.get();
} catch (IndexOutOfBoundsException e) {
error = "Ringbuffer schon leer";
}
repaint();
return ret;
}

static int element = 0;

/**
* Gesamtes Fenster zeichnen mit Buttons etc.
*
* @param args
*/
public static void main(String[] args) {
final GraphView view = new GraphView();
JFrame f = new JFrame("Ringbuffer");
f.setSize(500, 200);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane pane = new JScrollPane(view);
JPanel panel = new JPanel(new BorderLayout());
panel.add(pane, BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout());
JButton putButton = new JButton("put");
putButton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
element++;
view.put("" + element);
}

});
JButton getButton = new JButton("get");
getButton.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
view.get();
}

});
buttons.add(putButton);
buttons.add(getButton);
panel.add(buttons, BorderLayout.SOUTH);
f.setContentPane(panel);
f.setVisible(true);
}
}


Der Code ist kein gutes Beispiel für Programmierstil, weil ziemlich viele Konstante für die grafische Aufbereitung einfach im Code stehen.

Labels: , ,


 

Simulation einer Warteschlange an der Kasse

Schreiben Sie ein Programm, welches die Warteschlange an einer Kasse simuliert.
Es sollen in beliebigen Abständen Namen der Kunden eingegeben werden können, die sich an der Kasse anstellen.
Die Kasse bedient nun einen Kunden nach dem anderen. Die Bearbeitungsdauer soll zufällig aus einem Intervall von 5 bis 10 Sekunden gewählt werden. In regelmäßigen Abständen soll die Warteschlange bzw. die Anzahl der Kunden ausgegeben werden:



hp@L309:~/queue/bin> java kassa/Warteschlange
Marina Kathi Klaus Susi
es warten: Marina Kathi Klaus Susi
Tom es warten: Marina Kathi Klaus Susi
bediene Marina
Manues warten: Kathi Klaus Susi
Marina fertig
elaes warten: Kathi Klaus Susi
bediene Kathi

es warten: Klaus Susi Tom Manuela
es warten: Klaus Susi Tom Manuela
es warten: Klaus Susi Tom Manuela
es warten: Klaus Susi Tom Manuela
Kathi fertig
es warten: Klaus Susi Tom Manuela
bediene Klaus
es warten: Susi Tom Manuela
es warten: Susi Tom Manuela
es warten: Susi Tom Manuela
es warten: Susi Tom Manuela
Klaus fertig
es warten: Susi Tom Manuela
bediene Susi
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
Susi fertig
es warten: Tom Manuela
bediene Tom
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
Tom fertig
es warten: Manuela
bediene Manuela
Manuela fertig

Normalerweise würde man so etwas mit Threads programmieren. Es gibt aber auch eine andere Möglichkeit durch die Verwendung eines InputStreamReader. Ein InputStreamReader besitzt eine nicht blockierende Methode um abzufragen, ob Eingabe vorhanden ist: ready(). Zum Lesen kann dann trotzdem ein BufferedReader verwendet werden, der den InputStreamReader verwendet:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
...
InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(instream);

Damit kann man den Eingabestrom pollen:

boolean eof = false;
while (!eof) {
// poll
if (instream.ready()) { // is there something to read?
String zeile = in.readLine(); // yes, read it
System.out.println("------- " + zeile);
if (zeile.equalsIgnoreCase("quit")) {
eof = true;
}
} else {
// no, do the other work...
Thread.sleep(500); // wait 500 ms
}
}
in.close();

Warteschlange als Ringpuffer

Eine Warteschlange besitzt drei Operationen:

put(element) ein Element in die Warteschlange aufnehmen.
get() das erste Element entfernen.
isEmpty() prüft, ob die Schlange leer ist.

Array

Werden Daten in dieses Array aufgenommen und wieder entnommen, so kommt man bald ans Ende des Arrays. Man muss also wieder von vorne beginnen. Daher kann man sich das Array als Ring vorstellen:

Ringbuffer

Man benötigt zwei Zeiger (Indices), einen putIndex für die Schreiboperation put() und einen getIndex für die Leseoperation get().
Der Leseindex (getIndex) muss immer hinter dem Schreibindex (putIndex) sein. Sind beide Indices gleich, so ist der Puffer entweder leer oder ganz voll. Um dies zu unterscheiden, könnte man einen Füllstand einführen (usedSize).

public class Queue {
public static final int DEFAULTSIZE = 10;
private int size; // size of ringbuffer/queue
private int usedSize; // so many elements are in the ringbuffer
private char[] ring; // the ringbuffer
private int getIndex = 0;
private int putIndex = 0;

public void put(char elem) {
usedSize++;
ring[putIndex] = elem;
putIndex = (putIndex + 1) % size;
}

public char get() {
usedSize--;
char ret = ring[getIndex];
getIndex = (getIndex + 1) % size;
return ret;
}

public Queue(int size) {
this.size = size;
ring = new char[size];
}

public Queue() {
size = DEFAULTSIZE;
ring = new char[size];
}

public boolean isEmpty() {
return usedSize == 0;
}

public int getSize() {
return size;
}
}

Queue.java enthält dokumentierten Sourcecode (Achtung Package queue) inklusive Fehlerbehandlung (die man normalerweise mit Exceptions machen würde) für eine Schlange von char.

Labels: , ,


Montag, 11. Januar 2010

 

Prüfen Sie Ihr Wissen

Sie finden an dieser Stelle eine Reihe von Fragen und Aufgaben, die Sie etwa Mitte des zweiten Jahrgangs EDVO beantworten bzw. lösen können sollten.

Theorie
  1. Was ist eine Variable?
  2. Welche Grunddatentypen kennen Sie? Geben Sie auch den Speicherbedarf und den Wertebereich an.
  3. Was versteht man unter den Eigenschaften eines Objekts? Wie spiegelt sich das in einer Klasse wieder?
  4. Welche Kontrollstrukturen kennen Sie?
  5. Was ist ein Array?
  6. Geben Sie ein Beispiel eines eindimensionalen Arrays in Java an.
  7. Wie kann man ein eindimensionales Array in Java initialisieren?
  8. Geben Sie ein Beispiel eines zweidimensionalen Arrays in Java an.
  9. Wie kann man ein zweidimensionales Array in Java initialisieren?
  10. Kann man in Java ein zweidimensionales Array definieren, welches "nicht rechteckig" (rechteckig bedeutet hier: alle Zeilen gleich lang) ist?
  11. Geben Sie einen Algorithmus (ohne Programmdetails) an, um alle Elemente eines eindimensionalen Arrays zu ermitteln, die ein bestimmtes Kriterium (z.B. ist größer als ein bestimmter Wert) erfüllen.
  12. Geben Sie einen Algorithmus (ohne Programmdetails) an, um alle Elemente eines zweidimensionalen Arrays zu ermitteln, die ein bestimmtes Kriterium erfüllen.
  13. Geben Sie einen Algorithmus (ohne Programmdetails) an, um das Maximum aller Werte eines eindimensionalen Arrays zu ermitteln.
  14. Geben Sie einen Algorithmus (ohne Programmdetails) an, um das Minimum aller Werte eines eindimensionalen Arrays zu ermitteln.
  15. Geben Sie einen Algorithmus (ohne Programmdetails) an, um das Maximum aller Werte eines zweidimensionalen Arrays zu ermitteln.
  16. Geben Sie einen Algorithmus (ohne Programmdetails) an, um das Minimum aller Werte eines zweidimensionalen Arrays zu ermitteln.
  17. Was ist eine Funktion? Geben Sie ein Beispiel in Java inklusive der Verwendung der Funktion.
  18. Was ist eine Methode? Geben Sie ein Beispiel in Java inklusive der Verwendung der Funktion.
  19. Was ist der Unterschied zwischen einer Variable eines Grunddatentyps und einer Variable vom Typ einer Klasse?
  20. Was ist eine Klasse?
  21. Was ist ein Objekt? Erklären Sie den Zusammenhang zwischen Objekt und Klasse.
  22. Was sind Strings?
  23. Wie kann man Strings vergleichen?
  24. Was ist ein Stack? Beschreiben Sie die Eigenschaften und Methoden.
  25. Was ist eine Queue? Beschreiben Sie die Eigenschaften und Methoden.
  26. Wozu benötigt man Kommentare?
  27. Wozu benötigt man Programmierrichtlinien?
  28. Vergleichen Sie Java mit Python.
  29. Was ist ein Dictionary in Python?
  30. Was bedeutet der Begriff "Sequenz" in Python? Geben Sie einige Beispiele.
  31. Woran soll Sie die Geschichte "Shlemiel the Painter" erinnern?
  32. Was muss grundsätzlich (ohne Programmdetails) gemacht werden, um von einer Datei zu lesen?
  33. Was muss grundsätzlich (ohne Programmdetails) gemacht werden, um in eine Datei zu schreiben?
  34. Geben Sie einen Algorithmus (ohne Programmdetails) an, um alle Zeilen einer Textdatei zu ermitteln, die ein bestimmtes Kriterium (z.B. enthält einen bestimmten String) erfüllen.
  35. Welche Arten von Programm(ier)fehlern kennen Sie? Wie findet man diese Fehler?
  36. Wieviele main()-Methoden muss eine Java-Klasse besitzen?
  37. Wieviele main()-Methoden kann eine Java-Klasse maximal haben?
  38. Wieviele Klassen können in einer einzelnen Java-Datei implementiert werden?
  39. Welchen Wert hat die Variable einInteger? Begründen Sie Ihre Antwort!
    int einInteger = Integer.MAX_VALUE + 1;
  40. Was versteht man unter impliziter bzw. expliziter Typumwandlung? Nennen Sie jeweils mindestens ein Beispiel.
  41. Erläuten Sie den Unterschied zwischen String und StringBuffer!
  42. Finden Sie Klassen bzw. Objekte zu folgenden Begriffen: Leo, Tiger, Samurai, Elefant, Taigon, Benjamin Blümchen, Tier, Löwe
    Zeichnen Sie das Objekt-/Klassendiagramm
  43. Implementieren Sie die Klassen aus Frage 42 in Java! Wie werden Objekte angelegt?
  44. Implementieren Sie die Klassen aus Frage 42 in Python! Wie werden Objekte angelegt?
  45. Was ist der Aufrufstack? Erklären Sie den Verwendungszweck und die Funktionsweise.
Praxis:
In diesem Blog und auch im alten Blog gibt es bereits eine Reihe von Aufgaben. Vergleichen Sie Ihre Lösungen mit jenen Ihrer MitschülerInnen.
Hier noch ein paar "Grundübungen":
  1. Erstellen Sie ein Pythonprogramm, welches das Maximum einer Sequenz ermittelt. Definieren Sie dazu eine fixe Testsequenz mit folgenden Werten [-1, -23, -2, -32, -89, -100, -1, -99]. Finden Sie weitere Beispieltestdaten.
  2. Erstellen Sie ein Pythonprogramm, welches das Minimum einer Sequenz ermittelt. Definieren Sie dazu eine fixe Testsequenz mit folgenden Werten [1, 23, 2, 32, 89, 100, 1, 99]. Finden Sie weitere Beispieltestdaten.
  3. Erstellen Sie ein Javaprogramm, welches das Maximum einer Sequenz ermittelt. Definieren Sie dazu eine fixe Testsequenz mit folgenden Werten [-1, -23, -2, -32, -89, -100, -1, -99]. Finden Sie weitere Beispieltestdaten.
  4. Erstellen Sie ein Javaprogramm, welches das Minimum einer Sequenz ermittelt. Definieren Sie dazu eine fixe Testsequenz mit folgenden Werten [1, 23, 2, 32, 89, 100, 1, 99]. Finden Sie weitere Beispieltestdaten.
  5. Erstellen Sie ein Pythonprogramm, welches die Häufigkeit von Elementen einer Sequenz (Liste) ermittelt. Definieren Sie dazu eine Testsequenz mit folgenden Werten [1, 2, -3, 4, 2, 1, 10, -3, 4, 2, 2, 10] bzw. ["hallo", "du", "test", "du", "Maus", "test", "Test"]. Das Ergebnis soll eine Liste von unterschiedlichen Werten sein und wie oft sie vorkommen.
  6. Betrachten Sie die Methode dividiere im folgenden Programm. lässt sich das Programm übersetzen? Falls nicht, dann korrigieren Sie die Fehler:
    public class DivisionApp {
    public static void main(String[] args) {
    int ergebnis = dividiere(40, 5);
    System.out.println("Ergebnis: " + ergebnis);
    }

    public static int dividiere(int divident, int divisor) {
    if (divisor > 0) {
    return divident / divisor;
    }
    }
    }

  7. Folgende Ausgabe soll erzeugt werden: 1 3 5 7 9. Lösen Sie die Aufgabe
    • mithilfe einer while-Schleife
    • mithilfe einer do-while-Schleife
    • mithilfe einer for-Schleife und des Modulo-Operators
    • mithilfe einer for-Schleife ohne den Modulo-Operator

  8. Folgende Ausgabe soll erzeugt werden: 1 2 4 7 11 16 22 29 37. Lösen Sie die Aufgabe
    • mithilfe einer do-while-Schleife
    • mithilfe einer for-Schleife
  9. Schreiben Sie ein Java-Programm, welches mithilfe eines Stacks folgende Werte in umgekehrter Reihenfolge ausgibt: 23 21 20 18 17 13 11 5 3
  10. Schreiben Sie ein Java-Programm, welches mithilfe einer Queue folgende Werte in derselben Reihenfolge ausgibt: 23 21 20 18 17 13 11 5 3
  11. Schreiben Sie auf Basis der letzten beiden Beispiele Programme, die Strings statt der Integer-Werte verwenden können.

Labels: ,


Freitag, 8. Januar 2010

 

Abgaben am CVS - Reloaded

Ich möchte noch einmal auf die Richtlinien für Projektbezeichnungen für Abgaben über cvs.htlwrn.ac.at hinweisen.
klasse-familienname-projektname
Optional mit Angabe der Sprache:
klasse-familienname-sprache-projektname
Projekte, die nicht nach dieser Regel abgegeben wurden, können nicht positiv bewertet werden.
Sollten Arbeiten als Team gemacht/abgegeben werden, dann müssen die Namen aller Teammitglieder angegeben werden. Erstellen Sie im Projektverzeichnis eine Datei README, in der die Teammitglieder und ggf. die Aufgabenverteilung angegeben ist.
klasse-name1-name2-name3-projektname
Wurde bei der Aufgabenstellung kein Projektname angegeben, dann fragen Sie bei mir nach bzw. kommentieren Sie die Aufgabenstellung hier im Blog.
Nicht alle Aufgaben sind in diesem Blog zu finden, fragen Sie in diesem Fall MitschülerInnen oder mich.
Sollten sich Probleme mit der Abgabe am CVS ergeben, dann melden Sie sich bitte rechtzeitig - vor dem Abgabetermin (übrigens ist CVS eine Versionsverwaltung, d.h. es macht durchaus Sinn, das Projekt von Anfang an einzuchecken) - bei mir.
Beispiele ungültiger Projekte:
  • BugTracker
  • BugTracker_V3
  • 5AD-Eggenberger_BugTracker
Beispiele gültiger Projekte:
  • 5ad-grill-bugtracker
  • 2cd-buchegger-java-arruebung
  • 5ad-reischl-walker-bugtracker
Verwenden Sie als Kodierung (Text File Encoding) UTF-8!

Labels: , , ,


Donnerstag, 7. Januar 2010

 

begin - end - Klammerung prüfen mit Stack

Allgemeines

Realisieren Sie eine Klammerprüfung von beliebigen Ausdrücken in 2 Stufen. In den Ausdrücken sind folgende Klammern erlaubt:



(),
[],
Begin End,
{}

Beispiel:



Begin
(a+[b*c])
{
[5-(3/2)+1]
Begin (Num – Beg] End
}
End

Aufgabe 1 - Aufbereitung:

Schreiben Sie ein Programm Filter.java, welches beliebige Klammerausdrücke so aufbereitet, dass nur mehr die Klammern übrig bleiben. Die Klammerung für Begin und End soll durch '<' und '>' ersetzt werden.
Bsp.: Begin (a*(b+c)) End –> <(())>

Der Aufruf des Programmes soll folgende Möglichkeiten bieten:



java Filter [-h | -o ausgabedatei] [eingabedatei]

Die eingabedatei enthält die Klammerausdrücke. Wird kein Dateiname angegeben so wird von System.in gelesen.
Die aufbereiteten Ausdrücke werden auf die ausgabedatei geschrieben oder auf System.out, wenn das Argument fehlt.
Verwenden Sie die Klassen BufferedReader und PrintWriter zum Lesen und Schreiben der Textdateien.

Aufgabe 2 - Klammerprüfung:

Erstellen Sie ein Programm KlammerPruef.java, welches aufbereitete Klammerausdrücke einliest und mit Hilfe eines Stacks eine Klammerprüfung durchführt. Als Ergebnis geben Sie richtige Klammerung oder falsche Klammerung aus.

Aufruf:



java KlammerPruef [-h | -o ausgabedatei] [eingabedatei]

Die eingabedatei enthält die aufbereiteten Klammerausdrücke. Wird kein Dateiname angegeben so wird von System.in gelesen. Das Prüfergebnis wird auf die ausgabedatei geschrieben oder auf System.out wenn das Argument fehlt.

Hinweis:

verwenden Sie einen char-Stack

Labels: , ,


 

Einfacher Rechner mittels Stack - UPN-Rechner

Schreiben Sie ein Pogramm, welches einen Rechner für umgekehrt polnische Notation simuliert. Die umgekehrt polnische Notation (UPN) ist eine Postfix-Schreibweise, d.h. die Operatoren stehen immer nach den Operanden.
z.B: wird der Ausdruck 3 + 4 * 5 in UPN als 3 4 5 * + geschrieben. Diese Art von Ausdrücken ist besonders leicht zu interpretieren und zu berechnen, da man nur einen Stack benötigt.
Die Operanden werden auf den Stack gepusht. Wird ein Operator eingegeben, so werden die nötigen Operanden vom Stack gepoppt, die Operation ausgeführt und das Ergebnis wieder auf den Stack gepusht.
Folgendes Bild zeigt die Operationen für das Beispiel 3 4 5 * +:
UPN Rechner

Eingabeverarbeitung:

Ein Ausdruck soll eingegeben werden. Die Berechnung erfolgt dann nach Eingabe von Strg+D (EOF). Die einzelnen Elemente (Operanden und Opertoren) müssen mit whitespaces (Leerzeichen, Tabulatoren und Newlines) getrennt werden.

Hintergrund zu UPN:

UPN geht auf den polnischen Logiker Jan Lukasiewicz (1878-1956) zurück. UPN ist eine Schreibweise von Rechenoperationen, bei der das Verknüpfungssymbol hinter die zu verknüpfenden Operanden geschrieben wird und nicht dazwischen, wie allgemein üblich. Durch die daraus entstehende Schachtelung der Operationen ineinander, wird eine Klammersetzung unötig. Der Name Lukasiewicz ist für viele unaussprechlich, daher wird umgekehrt polnische Notation verwendet (engl. RPN reverse polish notation).

Labels: ,


This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]