Algorithmen und Programmierung II
Übungsblatt 9 - Musterlösung
Aufgabe 1
Das Programm wird durch die folgende schrittweise Verfeierung
entwickelt.
kursiv: zu verfeinernder
Schritt
- Main
- Stimmen lesen
- Anzahl der Sitze einlesen
(Int
Lesen)
- Verteilung berechnen
- Verteilung ausgeben
- Stimmen lesen
- Anzahl der Parteien lesen
(Int
Lesen)
- Feld erzeugen
- pro Partei deren Stimme einlesen
(Int
Lesen)
- Int Lesen
- wiederholt einlesen, bis erfolgreich
- Verteilung berechnen
- Feld mit ersten Höchstzahlen initialisieren
- solange Sitz zu vergeben
- Partei mit
größter Höchstzahl bestimmen
(Verfeinerung wird direkt eingefügt)
- dieser Partei den Sitz zuteilen
- neue Höchstzahl für diese Partei berechnen
- Partei mit größter
Höchstzahl bestimmen
- bisheriges Maximum merken
- mit jedem Feldelement vergleichen und ggf. Maximum aktualisieren
Fertiges Programm (Testlauf):
import java.io.*;
public class DHondt {
static BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
int[] stimmen = stimmenLesen();
int sitze = intLesen("Anzahl der Sitze: ");
int[] verteilung = verteilungBerechnen(stimmen, sitze);
verteilungAusgeben(verteilung);
}
static int[] stimmenLesen() throws IOException {
int anz = intLesen("Anzahl der Parteien: ");
int[] stimmen = new int[anz];
System.out.println("Stimmenzahl eingeben:");
for (int i = 0; i < stimmen.length; i++)
stimmen[i] = intLesen("Partei " + (i + 1) + ": ");
return stimmen;
}
static int intLesen(String nachricht) throws IOException {
System.out.print(nachricht);
for (;;)
try { return Integer.parseInt(br.readLine()); }
catch (NumberFormatException e) {
System.out.print(
"Zahl konnte nicht gelesen werden, bitte wiederholen: ");
}
}
static int[] verteilungBerechnen(int[] stimmen, int sitze) {
double[] hzahlen = new double[stimmen.length];
int[] verteilung = new int[stimmen.length];
for (int i = 0; i < stimmen.length; i++)
hzahlen[i] = stimmen[i];
while (sitze-- > 0) {
int partei = 0;
for (int i = 1; i < hzahlen.length; i++)
if (hzahlen[i] > hzahlen[partei]) partei = i;
verteilung[partei]++;
hzahlen[partei] = (double) stimmen[partei]
/ (verteilung[partei]+1);
}
return verteilung;
}
static void verteilungAusgeben(int[] verteilung) {
System.out.println("\nSitzverteilung:");
for (int p = 0; p < stimmen.length; p++)
System.out.println("Partei " + (p + 1) + ": " +
verteilung[p] + " Sitze");
}
}
Aufgabe 2
Ausgangspunkt für die Entwicklung ist die Beschreibung des
Programmverhaltens: Die Namen der Teilnehmer werden eingelesen, dann
werden ein oder mehrere Rennen durchgeführt, bis der Benutzer das
Programm beendet. Vor einem weiteren Rennen wird die Rangliste
gelöscht. Diese Schritte bilden das "Hauptprogramm" und werden als
Methoden realisiert, die schrittweise verfeinert werden.
Es werden zwei einfach verkettete Listen verwaltet: eine Startliste und
eine Rangliste. Für beide werden Klassen definiert, die die
relevanten Methoden zur Verfügung stellen. Elemente der Listen
sind Teilnehmer-Objekte.
Die Listen enthalten die selben Teilnehmer-Objekte
in unterschiedlichen Reihenfolgen. Neue Teilnehmer-Objekte werden am
Ende der Startliste eingefügt. In die Rangliste wird nach dem zeit-Attribut von Teilnehmer sortiert
eingefügt.
Der Schritt "Teilnehmer einlesen" wird in Form einer Schleife
realisiert, die beendet wird, wenn der Benutzer ohne Eingabe eines
Namens <return> drückt. Die Durchführung eines Rennens
besteht aus einer Schleife über alle Teilnehmer der Startliste.
Für jeden wird die Zeit eingelesen (verfeinert in intLesen), und das Teilnehmer-Objekt wird
(sortiert) in die Rangliste eingefügt (verfeinert in einfuegen in der Klasse Rangliste). Dann wird die
aktuelle Rangliste dargestellt (ausgeben
in der Klasse Rangliste).
import java.io.*;
public class Rennen {
static BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
static Startliste sl = new Startliste();
static Rangliste rl = new Rangliste();
public static void main(String[] args) throws IOException {
teilnehmerEinlesen();
int i = 1;
do {
System.out.println("\n" + (i++) + ". Rennen - Zeiten eingeben:");
rennen();
rl.loeschen();
} while(endeAbfragen());
}
static void teilnehmerEinlesen() throws IOException {
System.out.println("Namen eingeben (Beenden mit <return>):\n");
String name;
for (int i = 1; ; i++) {
System.out.print("Teilnehmer " + i + ": ");
name = br.readLine();
if (name.equals("")) break;
else sl.einfuegen(new Teilnehmer(name));
}
}
static boolean endeAbfragen() throws IOException {
String s = null;
do {
System.out.print("\nRennen beendet. Neues Rennen? (j/n) ");
s = br.readLine();
} while (s == null || !(s.equals("j") || s.equals("n")));
return s.equals("j");
}
static void rennen() throws IOException {
Teilnehmer t = sl.erster;
while (t != null) {
System.out.print("\nZeit für Teilnehmer \"" + t.name + "\": ");
t.zeit = intLesen();
rl.einfuegen(t);
rl.ausgeben();
t = t.naechsterStarter;
}
}
static int intLesen() throws IOException {
for (;;)
try { return Integer.parseInt(br.readLine()); }
catch (NumberFormatException e) {
System.out.print(
"Zahl konnte nicht gelesen werden, bitte wiederholen: ");
}
}
}
class Teilnehmer {
String name;
int zeit;
Teilnehmer naechsterStarter,
naechsterRang;
Teilnehmer(String name) {
this.name = name;
}
}
class Startliste {
Teilnehmer erster, letzter;
void einfuegen(Teilnehmer t) {
if (erster == null) {
erster = letzter = t;
} else {
letzter.naechsterStarter = t;
letzter = t;
}
}
}
class Rangliste {
Teilnehmer erster;
void einfuegen(Teilnehmer t) {
if (erster == null || erster.zeit >= t.zeit) {
t.naechsterRang = erster;
erster = t;
} else {
Teilnehmer test = erster, vorg = null;
do {
vorg = test;
test = test.naechsterRang;
} while (test != null && test.zeit < t.zeit);
t.naechsterRang = test;
vorg.naechsterRang = t;
}
}
void ausgeben() {
Teilnehmer t = erster;
System.out.println("\nRangliste:");
for (int i = 1; t != null; i++, t = t.naechsterRang)
System.out.println(i + ": " + t.name + " (" + t.zeit + " s)");
}
void loeschen() {
Teilnehmer test = erster;
erster = null;
while (test != null) {
Teilnehmer naechster = test.naechsterRang;
test.naechsterRang = null;
test = naechster;
}
}
}
Testlauf