Übungen zu Einführung in die Informatik I - TUM Seidl

Werbung
Technische Universität München
Fakultät für Informatik
A. Berlea, M. Petter,
Dr. M. Schneider, P. Ziewer
WS 2004/2005
Lösungsvorschläge zu Blatt 8
16. Dezember 2004
Übungen zu Einführung in die Informatik I
(Vorversion)
Aufgabe 23 Abstrakte Klassen (Lösungsvorschlag)
a) Sinnvollerweise werden die beiden Oberklassen Prisma und Regelmäßiges Prisma abstrakt deklariert. Das ergibt dann folgendes Klassendiagramm:
Prisma
# hoehe: Double
+ abstract inhaltGrundflaeche(): Double
+ abstract umfangGrundflaeche(): Double
+ mantelFlaeche(): Double
+ oberFlaeche(): Double
+ mvolumen(): Double
+ compareVolumenTo(Prisma p): Integer
RegelmaessigesPrisma
# seite: Double
Wuerfel
+ inhaltGrundflaeche(): Double
+ umfangGrundflaeche(): Double
RegelmaessigesDreiecksPrisma
+ inhaltGrundflaeche(): Double
+ umfangGrundflaeche(): Double
QuadratischerQuader
+ inhaltGrundflaeche(): Double
+ umfangGrundflaeche(): Double
Quader
− laenge: Double
− breite: Double
+ inhaltGrundflaeche(): Double
+ umfangGrundflaeche(): Double
Zylinder
− radius: Double
+ inhaltGrundflaeche(): Double
+ umfangGrundflaeche(): Double
RegelmaessigesSechsecksPrisma
+ inhaltGrundflaeche(): Double
+ umfangGrundflaeche(): Double
b) Die Klasse Prisma lautet dann:
abstract public class Prisma {
// Gemeinsames Attribut aller Prismen ist die Hoehe:
protected double hoehe;
// Konstruktor:
public Prisma (double h) {
hoehe = h;
}
// Die Operationen umfangGrundflaeche() und inhaltGrundflaeche()
// sind abhaengig von der Form des konkreten Prismas und koennen
// hier nur abstrakt definiert werden:
Lösung 8/ Seite 2
abstract public double umfangGrundflaeche();
abstract public double inhaltGrundflaeche();
// Die anderen Operationen koennen bereits in dieser Klasse implementiert
// werden:
// .......
}
die Klasse Regelmaessiges Prisma:
abstract public class RegelmaessigesPrisma extends Prisma {
// alle Grundflaechen regelmaessiger Prismen sind gleichseitige
// Vielecke. Als zusaetzliches Attribut genuegt die Seitenlaenge:
protected double seite;
// Konstruktor:
public RegelmaessigesPrisma(double h, double s) {
super(h);
seite = s;
}
}
Aufgabe 24 Telefonbäume (Lösungsvorschlag)
a) Ein UML-Diagramm zur Beschreibung der erforderlichen Klassen, könnte folgendes Aussehen haben:
Node
PhoneTree
tree
+ main()
+ getName()
+ insert()
10
followingNumbers
+ isLeaf()
+ getName()
NameNode
NumberNode
− name: String
+ isLeaf()
+ getName()
b) Telefonnummern:
• int:
max 10 Stellen; keine führende 0 erlaubt
+ isLeaf()
+ getName()
+ insert()
Lösung 8/ Seite 3
• long:
mehr Stellen; auch keine führende 0 erlaubt;
nicht als Feldindex verwendtbar (cast notwendig)
• String:
viele Stellen inklusive führender 0;
extrahieren einer Ziffer mittels number.charAt(position) - ’0’ liefert ASCII-Wert
zwischen 0 und 9, der als Feldindex verwendtbar ist
Der detaillierte Entwurf hat demzufolge folgendes Aussehen:
Node
PhoneTree
+ main(args : String[])
+ getName(number : String)
+ insert(number : String,
name : String)
tree
+ isLeaf()
+ getName(number : String, position : Integer)
+ insert(number : String, position : Integer, name: String)
10
followingNumbers
NameNode
− name: String
+ isLeaf()
+ getName(number : String, position : Integer)
+ insert(number : String, position : Integer, name: String)
NumberNode
+ isLeaf()
+ getName(number : String, position : Integer)
+ insert(number : String, position : Integer, name: String)
c) Die Implementierung der verschiedenen Klassen lautet:
abstract public class Node {
abstract public boolean isLeaf();
abstract public String getName(String number, int position);
abstract public void insert(String number, int position, String name);
}
public class NameNode extends Node {
private String name;
public NameNode(String name) {
this.name = name;
}
public boolean isLeaf() {
return true;
}
// liefert den gespeicherten Namen zurück
public String getName(String number, int position) {
Lösung 8/ Seite 4
return name + " (" + number.substring(0, position) + ")";
}
// überschreibt den Namen
public void insert(String number, int position, String name) {
this.name = name;
}
}
public class NumberNode extends Node {
private Node[] followingNumbers = new Node[10];
public boolean isLeaf() {
return false;
}
// Einfügen von eines Namens unter einer Nummer
// zusätzlich zu Nummer und Name wird angegeben, welche Position
// innerhalb der Telefonnummer gerade betrachtet wird
public void insert(String number, int position, String name) {
int index = getDigit(number, position); // index bestimmen
if (index < 0 || 9 < index)
return; // Fehler in number
if (position + 1 == number.length()) {
// Blatt mit Namen einfügen
if (followingNumbers[index] != null && followingNumbers[index].isLeaf())
// verwende Blatt, falls vorhanden
followingNumbers[index].insert(number, position, name);
else
// neues Blatt
followingNumbers[index] = new NameNode(name);
} else {
// innerer Knoten
if (followingNumbers[index] == null || followingNumbers[index].isLeaf()) {
// Knoten neu anlegen falls notwendig
followingNumbers[index] = new NumberNode();
}
// rekursiv einfügen
followingNumbers[index].insert(number, position + 1, name);
}
}
// liefert Namen zu Nummer
// auch hier wird angegeben, welche Position
// innerhalb der Telefonnummer gerade betrachtet wird
public String getName(String number, int position) {
// index bestimmen
int index = getDigit(number, position);
if (index != -1 && followingNumbers[index] != null) {
// rekursiv suchen
return followingNumbers[index].getName(number, position + 1);
} else {
// nicht enhalten
Lösung 8/ Seite 5
return "[unbekannte Nummer: " + number + "]";
}
}
// Hilfsfunktion zum Extrahieren einer Ziffer aus number an Position position
// ganz einfach ohne Fehlerbehandlung
private static int getDigit(String number, int position) {
return number.charAt(position) - ’0’;
}
}
public class PhoneTree {
private NumberNode tree = new NumberNode();
public void insert(String number, String name) {
System.out.println("einfügen von " + number + " " + name);
tree.insert(number, 0,name);
}
public String getName(String number) {
return "suche nach " + number + " ergab " + tree.getName(number,0);
}
public static void main(String[] args) {
PhoneTree phoneTree = new PhoneTree();
phoneTree.insert("028918157", "Sekretäriat Seidl");
phoneTree.insert("028918161", "Fax Seidl");
phoneTree.insert("02890", "Uni");
System.out.println(phoneTree.getName("028918157"));
System.out.println(phoneTree.getName("028918161"));
System.out.println(phoneTree.getName("028918160"));
System.out.println(phoneTree.getName("02890"));
phoneTree.insert("028918161", "Fax2 Seidl");
System.out.println(phoneTree.getName("028918161"));
phoneTree.insert("0289", "Uni Vorwahl");
System.out.println(phoneTree.getName("028918161"));
}
}
Herunterladen