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: , ,


Samstag, 20. März 2010

 

Teilnahme an der RobotChallenge 2010

Unser Team Robert nahm heute an der RobotChallenge 2010 teil. Leider nur ein Teilerfolg, aber lesen Sie hier mehr.

Labels:


Freitag, 19. März 2010

 

Probleme mit python's random

Wenn man Zufallszahlen benötigt oder Funktionen, die auf zufällige Zahlenfolgen basieren, verwendet man in Python das Modul random (ähnliche Module, Klassen oder Libraries gibt es im Prinzip für alle Programmiersprachen). Dahinter steckt keine echte Zufallszahlenerzeugung sondern vielmehr eine Funktion, welche Pseudozufallszahlen liefert, die sich statistisch wie Zufallszahlen verhalten.
Manchmal benötigt man immer wieder die selbe Zahlenfolge (z.B. beim Testen). Das erreicht man durch Angabe eines "seeds" (Samen) bei der Methode random.seed(), z.B. random.seed(23). Damit wird der Zufallsgenerator mit diesem Wert initialisiert. Bei selbem seed bekommt man immer die selbe Folge von Pseudozufallszahlen. Verwendet man diese Funktion nicht, so wird (zumindest bei Python) automatisch die Systemzeit als Anfangswert genommen. Damit kann man die Folge nicht vorhersagen (für einen bestimmten Zeitpunkt schon, dann nimmt man diesen Zeitstempel einfach als seed).

Nun zu meinem Problem mit random:
Python 2.5.2 auf meinem Debian- Rechner, den ich regelmäßig auf neuen Stand bringe
>>> from random import seed, random
>>> seed("23")
>>> random()
0.41111702255082994
Python 2.5.1 auf der Dreambox
>>> from random import seed, random
>>> seed("23")
>>> random()
0.09256672412670508

Bis vor Kurzem waren die beiden Werte identisch. Mein Python-Programm verhielt sich auf der Dreambox genauso wie auf meinem Entwicklungsrechner.

Offensichtlich gab es da Änderungen (Korrekturen) in der Python-Bibliothek.

In der Dokumentation von Python kann man lesen, dass für den seed ganze Zahlen (long, int) oder jedes "hashable" Objekt verwenden kann. Und dort dürfte das Problem liegen:
Python 2.5.2
>>> "23".__hash__()
6400038450057767
Python 2.5.1
>>> "23".__hash__()
308105767

Es ist einiges an Zeit vergangen, bis ich dieses Problem identifizieren konnte, denn der Bytecode von Python ist auf jeder Maschine gleich (ähnlich der VM von Java). Es muss also m.E. an der Version liegen.

Als Lösung bietet sich an, direkt eine Zahl zu verwenden:
Python 2.5.2
>>> seed(23)
>>> random()
0.92486525162594524
Python 2.5.1
>>> seed(23)
>>> random()
0.92486525162594524

Quellen:

Labels: , ,


Donnerstag, 18. März 2010

 

Kompetenzmatrix - was muss ein Programmierer können?

Unter folgendem Link sind die Kompetenzstufen von Programmierern ganz gut zusammengefasst.
http://www.indiangeek.net/programmer-competency-matrix/

Es ist ein weiter Weg von Stufe 0 auf Stufe 3.

Labels: ,


Samstag, 13. März 2010

 

Android Grundlagen der Programmierung

Es gibt ein deutsches Buch zum Thema Android Programmierung, das momentan überarbeitet wird und "nur" das Android SDK bis 1.5 behandelt. Aber es ist frei als Download erhältlich.


Link zur Buch Seite: http://www.androidbuch.de/
Download von Chip: http://www.chip.de/

Es ist auch in der Schule am edvoftp zu finden /home/software/android.

Labels: ,


Donnerstag, 11. März 2010

 

UrlyBird-2010 - PR5

Die Aufgabenstellung zur Übung für die Projektwoche finden Sie am bscw - ich habe dazu alle Schüler der Klasse zum Verzeichnis PR5-2010 eingeladen. Sie finden dort eine Datei urlybird-2010.jar, welche im Verzeichnis Angabe eine PDF-Datei mit der Angabe/Anleitung zu diesem Beispiel enthält.
Der Abgabetermin ist für alle der 22. April 2010.
Alle weiteren Informationen finden Sie in dem Archiv bzw. in der PDF-Datei.

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: , ,


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

Abonnieren Posts [Atom]