Donnerstag, 28. Mai 2015
Aufgabe JTable (POS1:3BHIF)
Erstellen Sie ein Java-Programm, welches einfache CSV-Dateien erzeugen, darstellen und ändern kann. Verwenden Sie zur Darstellung der CSV-Datei eine JTable. Beim Neuanlegen wird die Anzahl der Spalten festgelegt. Beim Laden einer CSV-Datei wird die Anzahl der Zeilen/Spalten durch die Datei gegeben. Das Programm soll es ermöglichen, jede Zelle (definiert durch Zeile und Spalte) zu ändern. Sehen Sie eine Möglichkeit zum Einfügen neuer Zeilen vor. Eine markierte Zeile soll gelöscht werden können.
Die Beschriftung der Spalten soll in der ersten Zeile der Datei gespeichert werden bzw. wird beim Laden aus der ersten Zeile der Datei entnommen.
Labels: Aufgabe, GUI, Java, POS1-3
Mittwoch, 20. Mai 2015
Berechnungen mit Threads parallelisieren (POS1: 3BHIF)
π kann mit Hilfe der folgenden Formel von Strömer (1986) berechnet werden:
π / 4 = 44 · arctan 1/57 + 7 · arctan 1/239 - 12 · arctan 1/682 + 24 · arctan 1/12943
Der Arcustangens wird mit der folgenden Reihenentwicklung
arctan(x) = x - x3/3 + x5/5 - x7/7 + ...
berechnet.
Folgendes Java-Programm verwendet die Klasse BigDecimal
zur Berechnung von π. Es soll mittels Threads parallelisiert werden.
import java.math.*; /** * @author Hans Joachim Pflug, RZ, RWTH Aachen * * Berechnet PI auf eine beliebige Anzahl von Stellen genau */ public class Pi { private int dec; //Anzahl der Dezimalstellen private BigDecimal pi = new BigDecimal(0); //Ergebnis private MathContext m; //Zur Bestimmung der Laenge der Brueche private static final BigDecimal one = new BigDecimal(1); private static final BigDecimal four = new BigDecimal(4); private BigDecimal r57; // 1/57 private BigDecimal r239; // 1/239 private BigDecimal r682; // 1/682 private BigDecimal r12943; // 1/12943 /** * Erzeugt ein Objekt mit PI auf die angegebene Stellenzahl genau * @param dec Die Stellenzahl, auf die PI berechnet werden soll. */ public Pi(int dec) { this.dec = dec; m = new MathContext(dec + 5); //5 als Reserve r57 = one.divide(new BigDecimal(57), m); r239 = one.divide(new BigDecimal(239), m); r682 = one.divide(new BigDecimal(682), m); r12943 = one.divide(new BigDecimal(12943), m); calculate(); } /** * Berechnet den Wert von PI nach der Formel von Stoermer (1896): * pi/4 = 44 * arctan(1/57) + 7 * arctan(1/239) - 12 * arctan(1/682) * + 24 * arctan(1/12943) */ private void calculate() { BigDecimal sum1 = arctan(r57).multiply(new BigDecimal(44), m); BigDecimal sum2 = arctan(r239).multiply(new BigDecimal(7), m); sum1 = sum1.add(sum2, m); sum2 = arctan(r682).multiply(new BigDecimal(12), m); sum1 = sum1.subtract(sum2, m); sum2 = arctan(r12943).multiply(new BigDecimal(24), m); sum1 = sum1.add(sum2, m); pi = sum1.multiply(four, m); } /** * Berechnet den Arcustangens einer BigDecimal-Zahl. * Benutzt die Reihe: * arctan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... * @param arg Eingabewert * @return arctan(arg) */ private BigDecimal arctan(BigDecimal arg) { BigDecimal result = new BigDecimal(0); BigDecimal z; //Abschätzung der Anzahl der Iterationen //Nach der Formel n = - d / log10(x) // n: Anzahl der Iterationen // d: Anzahl der Stellen fuer Genauigkeit // x: Argument des Arcustangens //Zwei Stellen Genauigkeit zur Sicherheit int iter = (int) -((dec + 2)/ Math.log10(arg.doubleValue())); //Reihenentwicklung for (int i = 0; i < iter; i++) { int pow = 2 * i + 1; z = arg.pow(pow, m).divide(new BigDecimal(pow), m); if (i % 2 == 1) { z = z.negate(); } result = result.add(z, m); } return result; } /** * Gibt PI formatiert in 100er Bloecken zurueck */ public String toString() { String piS = pi.toString(); StringBuffer b = new StringBuffer(); b.append("3.1"); for (int i = 1; i < dec; i++) { if (i % 100 == 0) { b.append("\n "); } else if (i % 10 == 0) { b.append(" "); } b.append(piS.charAt(i + 2)); } return b.toString(); } public static void main(String args[]) { Pi p = new Pi(1000); System.out.println(p); } }
Wieviele Threads sind hier sinnvoll?
Vergleich zwischen serieller und paralleler Berechnung:
Zeitmessungen unter Linux auf einem Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz (Quadcore) (Intel(R) Core(TM) i3 CPU 560 @ 3.33GHz) mit 8GB RAM. Daneben wurden eclipse und chrome verwendet.
Stellen | sequentiell | 4 Threads |
---|---|---|
1000 | 4,395s | 2,530s |
2000 | 35,814s | 19,260s |
3000 | 126,145s | 65,693s |
4000 | 321,916s | 163,393s |
5000 | 626,394s | 323,876s |
6000 | 1132,480s | 568,905s |
7000 | 1800,781s | 912,360s |
8000 | 2753,654s | 1462,561s |
9000 | 3941,230s | 2134,741s |
10000 | 5527,330s | 2878,974s |
Bei der JVM kann man nicht bestimmen, ob und wie die Threads auf die CPUs (Kerne) aufgeteilt werden sollen. Die JVM und das Betriebssystem bestimmen, wie die Threads auf CPU-Kerne abgebildet werden. Das ist natürlich auch von der allgemeinen Systemlast abhängig.
Die Messungen zeigen, dass sich die Rechenzeit bei 4 Threads halbiert. Die CPU trägt zwar im Namen "Quadcore", tatsächlich ist es aber nur ein Dualcore mit vier Threads (siehe Link oben). Das bedeutet bei dieser Anwendung, dass nur zwei Threads echt parallel laufen können (weiter geteilt mit den anderen Prozessen, die auf dem System laufen).
Labels: algorithmen, Aufgabe, Java, POS1-3
Montag, 11. Mai 2015
Worthäufigkeiten mit binärem Baum ermitteln (POS1: 2BHIF)
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
hauf
.Labels: algorithmen, Aufgabe, Java, POS1-2
Aufgabe: Gruppenwechsel (POS1: 2BHIF)
Grw.java
, welches aus dem Datenbestand ski.csv die beigelegte Statistik erzeugt.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
. 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 GESCHLund 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,37
Sekunden betragen.Binäres Dateiformat für Eingabe
Erstellen Sie ein neues Programm so, dass sie statt der CSV-Eingabedatei auch eine Datei im binären Datenformat verwenden können. Die Daten sind wie folgt gespeichert (C-Datentypen):
typedef struct umsatz { char artikel[25]; char verkaeufer[25]; int vkpreis; int monat; } umsatz_t;Dabei ist
char artikel[25]
ein maximal 24-Zeichen langer String, bei dem jedes Zeichen (ASCII) als ein Byte gespeichert wird. Das Ende des Strings wird durch das Zeichen '\0'
abgeschlossen (das hat tatsächlich den Wert 0
). D.h. es müssen bis zu 25 Bytes gelesen werden, wobei nur die Zeichen bis exklusive '\0'
(direkt) in Java-char
s umgewandelt werden können (verwenden Sie z.B. RandomAccessFile.read(byte[] buf)
).int
entspricht einem 32-Bit-Integer und passt zum Java-Typ int
.Die passende Datei mit Testdaten finden Sie hier: daten.dat.
Den Inhalt dieser Datei kann man nur mit einem Programm öffnen, das die Daten binär lesen kann und sinnvoll, z.B. im Hexadezimalsystem, anzeigen kann.
khexedit
oder das Konsolenprogramm hexdump
eignen sich dafür.Die Ausgabe von
hexdump
könnte so aussehen (gekürzt):hp@L211 $ hexdump -C daten.dat 00000000 50 72 6f 64 30 31 00 01 4c 00 ba 01 e5 e2 e6 b7 |Prod01..L.......| 00000010 00 00 00 00 e4 98 04 08 28 4d 61 69 65 72 00 08 |........(Maier..| 00000020 a0 fc f5 b7 dc e9 b9 bf 48 e9 b9 bf f1 86 04 08 |........H.......| 00000030 90 8b f8 b7 dc 00 00 00 01 00 00 00 50 72 6f 64 |............Prod| 00000040 30 32 00 01 4c 00 ba 01 e5 e2 e6 b7 00 00 00 00 |02..L...........| 00000050 e4 98 04 08 28 4d 61 69 65 72 00 08 a0 fc f5 b7 |....(Maier......| 00000060 dc e9 b9 bf 48 e9 b9 bf f1 86 04 08 90 8b f8 b7 |....H...........| 00000070 90 01 00 00 02 00 00 00 50 72 6f 64 30 33 00 01 |........Prod03..| 00000080 4c 00 ba 01 e5 e2 e6 b7 00 00 00 00 e4 98 04 08 |L...............| 00000090 28 48 75 62 65 72 00 08 a0 fc f5 b7 dc e9 b9 bf |(Huber..........|
Es soll wieder ein 2-stufiger Gruppenwechsel programmiert werden (Artikel und Verkäufer).
Zum Vergleich können Sie die Daten auch im CSV-Format verwenden: daten.csv.
Versuchen Sie, die beiden Varianten, jene mit den Ski-Daten und jene mit den (binären) Umsatzdaten, so zu gestalten, dass nur geringe Teile unterschiedlich sind (am Besten austauschbare Klassen mit gleichem Namen für die Daten und für die Formatierung). Der Hauptalgorithmus bleibt ja gleich.
Labels: algorithmen, Aufgabe, Java, POS1-2
Abonnieren Posts [Atom]