Freitag, 9. Januar 2009

 

Integer aus Eingabestrom in Array, formatierte Ausgabe

Allgemeines

Erstellen Sie ein Projekt klasse-intNumbers-name, z.B. 2ad-intNumbers-mueller.

Schreiben Sie ein Programm zum Auffinden von ganzen Zahlen in Textdateien.

Die gefundenen Zahlen speichern Sie in einem int-Array und geben Sie am Ende der Verarbeitung in Tabellenform aus.

Aufgabe 1 – FindIntNumbers(), find(), fill()

Erstellen Sie eine Klasse FindIntNumbers mit einem Konstruktor FindIntNumbers(int value). value ist die, aus der Kommandozeile eingelesene Größe eines anzulegenden Arrays zum Speichern der Zahlen.

public void find(BufferedReader in) liest pro Datei bis zu EOF alle Zeichen des Streams ein und sucht nach ganzen Zahlen. Ganze Zahlen bestehen nur aus zusammenhängenden Ziffern (1-n, begrenzt durch den Wertebereich vom integer-Datentyp). Die Zahlen werden durch beliebige Zeichen getrennt. Die gefundenen Zahlen werden in einem StringBuffer zusammengestellt und mit der Methode fill() im angelegten Array abgespeichert.

public void fill(StringBuffer sb)füllt die Zahl aus dem StringBuffer in das nächste freie Arrayelement. (maximal size Zahlen!). Bei Array-Überlauf bitte eine Fehlermeldung auf stderr ausgeben.

Aufgabe 2 – toString()

public String toString() erstellt aus dem Array die Ausgabe in Tabellenform.

Die Formatierung der Zahlen (Spaltenbreite) wird durch die größte gefundene Zahl bestimmt, damit die Zahlen in der Tabelle linksbündig ausgerichtet untereinander stehen. In einer Zeile der Tabelle dürfen nicht mehr als 80 Zeichen stehen!

Beispiel:

Tabelle der gefundenen Zahlen

43 515 45 43 3567 24 36 23

478 6 59 346 1356887656 266 57 3624

487 346 57 345 245 6 6 3

3567 4 2134 934 193 4 934 934

931 193 934 3498 1943 190843 314 143

4 4 43 13

zugehörige Eingabedatei:

43 515 45 43 3567 24 36 23 478 6 59 346 1356887656 266 57 3624 487 346 57 345

245 6 gfr 6z3 qg tg rtg3567 4g

sadjfhalsd 2134h c934h fcnc193h4c nx934hc934ncjkd c931hqnc193hcudc 934

3498f 1943j190843jx n314dj143..4.4.43c13

Aufgabe 3 – main()

Erstellen Sie eine main()-Methode, sodass die Klasse als Programm verwendet werden kann.

Das Programm soll beliebig viele Dateien durchsuchen oder von der Standardeingabe lesen, wenn kein Dateiname angegeben ist. Die Ausgabe soll immer auf Standardausgabe erfolgen.

Aufruf:

java FindIntNumbers [-h] size [dat1 ... datn]

-h ... Hilfe ausgeben und Programm beenden

size ... Zahl, welche die Größe des Arrays angibt

dat1,datn ... aus diesen Dateien wird gelesen

Aufrufbeispiele:

java FindIntNumbers -h ... gibt Hilfe aus und sonst nichts

java FindIntNUmbers 200 dat.txt text.txt ... versucht alle Zahlen in den Dateien dat.txt und text.txt zu finden und gibt maximal die ersten 200 aus..

java FindIntNUmbers 100 ... liest aus der Standardeingabe und sucht nach allen Zahlen und gibt maximal 100 aus.


Lösungsansatz:
Die Klasse FindIntNumbers benötigt folgende Informationen (Eigenschaften):


private static final int zeilenLaenge = 80;
private int[] array;
private int arraySize = 0;
private int fillTo = 0;
private int max = 0;

Im Konstruktor wird das Array angelegt.
Die Methode find() liest aus dem BufferedReader zeichenweise und ermittelt die Zahlen (in einem StringBuffer zusammengebaut) und füllt das Array mittels fill(). find() implementiert einen einfachen Automaten mit zwei Zuständen inZahl und nicht inZahl um zu unterscheiden, ob gerade eine Zahl aus den Eingabezeichen "zusammengebaut" wird oder nicht:

public void find(BufferedReader in) throws IOException {
int c;
boolean inZahl = false;
StringBuffer sb = new StringBuffer();
while ((c = in.read()) != EOF) {
if (inZahl) {
if (!Character.isDigit((char) c)) {
inZahl = false;
fill(sb);
sb = new StringBuffer();
} else {
sb.append((char) c);
}
} else {
if (Character.isDigit((char) c)) {
inZahl = true;
sb.append((char) c);
}
}
}
}

fill() prüft, ob noch Platz im Array ist und konvertiert den StringBuffer in einen int und ermittelt gleichzeitig das Maximum für die Formatierung der Ausgabe (längste Zahl).

public void fill(StringBuffer sb) {
if (fillTo < arraySize) {
array[fillTo] = Integer.parseInt(sb.toString());
if (array[fillTo] > max) {
max = array[fillTo];
}
//System.out.printf("filled %d into array[%d]\n", array[fillTo], fillTo);
fillTo++;
}
}


Die Methode toString() macht die gesamte Formatierungsarbeit, indem zunächst ein Formatstring erstellt wird, bei dem die Länge mittels der Funktion maxlen() eingetragen wird. Die Anzahl der Zahlen pro Zeile ergibt sich aus der Division aus zeilenLaenge / maxlen(). maxlen() liefert die Länge der größten Zahl plus eins (für den Zwischenraum).

public String toString() {
StringBuffer sb = new StringBuffer();
String format = String.format("%%-%dd", maxlen());
int anzZahlenProZeile = zeilenLaenge / maxlen();
int spaltennummer = 0;
for (int i = 0; i < fillTo; i++) {
int zahl = array[i];
sb.append(String.format(format, zahl));
spaltennummer++;
if (spaltennummer >= anzZahlenProZeile) {
spaltennummer = 0;
sb.append("\n");
}
}
if (spaltennummer > 0) {
sb.append("\n");
}
return sb.toString();
}


Das gesamte Programm könnte folgendermaßen aussehen:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* lehrer-intNumbers-haberstroh: .FindIntNumbers.java
*
* 17.12.2008, Harald R. Haberstroh
*/

/**
* Auffinden von ganzen Zahlen in Dateien und speichern in einem Array.
*
* @author Harald R. Haberstroh (hp)
*
*/
public class FindIntNumbers {

private static final int EOF = -1;
private static final int zeilenLaenge = 80;
private int[] array;
private int arraySize = 0;
private int fillTo = 0;
private int max = 0;

/**
* @param arraySize
*/
public FindIntNumbers(int arraySize) {
this.arraySize = arraySize;
this.array = new int[this.arraySize];
this.fillTo = 0;
this.max = Integer.MIN_VALUE;
}

/**
* default Konstruktor
*/
public FindIntNumbers() {
this(10);
}

/**
* liest bis EOF und ermittelt alle ganzen Zahlen und speichert sie im Array.
*
* @param in
* Eingabestrom
* @throws IOException
*/
public void find(BufferedReader in) throws IOException {
int c;
boolean inZahl = false;
StringBuffer sb = new StringBuffer();
while ((c = in.read()) != EOF) {
if (inZahl) {
if (!Character.isDigit((char) c)) {
inZahl = false;
fill(sb);
sb = new StringBuffer();
} else {
sb.append((char) c);
}
} else {
if (Character.isDigit((char) c)) {
inZahl = true;
sb.append((char) c);
}
}
}
}

/**
* liefert maxmale Länge einer Zahl in Zeichen.
*
* @return maximale Länge + 1
*/
private int maxlen() {
return Integer.toString(max).length() + 1;
}

/**
* füllt die Zahl im Stringbuffer in die nächste freie Stelle von array.
*
* @param sb
*/
public void fill(StringBuffer sb) {
if (fillTo < arraySize) {
array[fillTo] = Integer.parseInt(sb.toString());
if (array[fillTo] > max) {
max = array[fillTo];
}
System.out.printf("filled %d into array[%d]\n", array[fillTo], fillTo);
fillTo++;
}
}

/**
* liefert schön formatierte Tabelle als String.
*
* @return Tabella als String.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
String format = String.format("%%-%dd", maxlen());
int anzZahlenProZeile = zeilenLaenge / maxlen();
int spaltennummer = 0;
for (int i = 0; i < fillTo; i++) {
int zahl = array[i];
sb.append(String.format(format, zahl));
spaltennummer++;
if (spaltennummer >= anzZahlenProZeile) {
spaltennummer = 0;
sb.append("\n");
}
}
if (spaltennummer > 0) {
sb.append("\n");
}
return sb.toString();
}

/**
* @param args
*/
public static void main(String[] args) {
if (args.length >= 1) {
if (args[0].equals("-h")) {
System.out.println("Aufruf: java FindIntNumber [-h] size [dateien...]");
} else {
try {
int size = Integer.parseInt(args[0]);
BufferedReader in;
FindIntNumbers fn = new FindIntNumbers(size);
if (args.length > 1) { // Dateien
for (int i = 1; i < args.length; i++) {
in = new BufferedReader(new FileReader(args[i]));
fn.find(in);
in.close();
}
} else { // stdin
in = new BufferedReader(new InputStreamReader(System.in));
fn.find(in);
}
System.out.print(fn.toString());
} catch (NumberFormatException e) {
System.err.println("ungültige Größe angegeben, Hilfe mit -h");
} catch (IOException e) {
System.err.println("Ein-/Ausgabefehler: " + e.getLocalizedMessage());
}
}
} else {
System.err.println("keine Größe angegeben, Hilfe mit -h");
}
}

}

Labels: , , ,


Kommentare:

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

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

Abonnieren Posts [Atom]