Die führenden und endenden Leerzeichen können sehr einfach mit der Methode String.trim() entfernt werden. Beim Untersuchen des restlichen Strings müssen immer zwei aufeinanderfolgende Zeichen geprüft werden. Außerdem müssen Zeichen entfernt werden, daher verwende ich ein char array, welches flexibler als der String ist. Zum Entfernen eines Zeichens muss eine eigene Methode implementiert werden, da diese Funktionalität von Java nicht "native" zur Verfügung steht. In der Prüfschleife muss darauf geachtet werden, dass sich die Länge des Strings beim Entfernen von Zeichen ändert und in der Schleife die Zählvariable nur bei Gleichbleiben der Zeichenkette inkrementiert werden darf, ansonsten würden Zeichen übergangen werden.
/** * * Softwareentwicklung I - Exercise 4/1. * Scans String for unnecessary blanks. * In-source comments are followed by the described code. * * @author Daniel Brunthaler (0255054) * @version 1.0 * */ public class SpaceRemover { // punctuation marks according to the exercise specification. public static final char[] PUNCTUATION_MARKS = {'.',',',';',':','?','!'}; /** * Remove an element from a char array. * @param oldArray from which an element should be removed * @param element index of element which should be removed. * @return new char array in which the given element was removed. */ public static char[] remove(char[] oldArray, int element) { char newArray[] = new char[oldArray.length - 1]; for (int i = 0;i < element; i++) newArray[i] = oldArray[i]; for (int i = element;i < newArray.length;++i) newArray[i] = oldArray[i+1]; return newArray; } /** * Check if the given character is a punctuation mark. * @param sign character which should be checked. * @return if the given character is a punctuation mark. */ public static boolean isPunctuationMark(char sign) { for(int i=0;i < PUNCTUATION_MARKS.length;i++) { if(sign == PUNCTUATION_MARKS[i]) { return true; } } return false; } /** * Remove spaces from a given String. * @param text which should be "reformatted". * @return "reformatted" String. */ public static String removeSpaces(String text) { // Trim the String and convert it to a char array. char[] textChars = text.trim().toCharArray(); int i = 1; // Check every character in the given String. while (i < textChars.length-1) { // Check if actual character and the following in the String // is a space (ASCII-Code = 32). if(textChars[i] == 32 && textChars[i+1] == 32) { textChars = remove(textChars,i); // Check if actual character in the String is a punctuation mark // and the following is a space (ASCII-Code = 32). } else if(isPunctuationMark(textChars[i+1]) && textChars[i]==32) { textChars = remove(textChars,i); // Increment of the counter only if no character was removed. } else { i++; } } return new String(textChars); } public static void main(String[] args) { String prompt1 = "Fehlerhafter Text: "; String prompt2 = "Korrigierter Text: "; IO.write(prompt1); String text = IO.readLine(); // Loop to enable several entrys without need of // restarting the program. while (text.length() > 0) { IO.writeLn(prompt2 + removeSpaces(text)); IO.writeLn(" "); IO.write(prompt1); text = IO.readLine(); } } }
Ein- und Ausgabewerte werden zur besseren Veranschaulichung immer unter doppeltes Hochkomma gesetzt, diese werden nicht eingegeben.
Eingabewerte : " Test ! " Erwartete Ausgabe : "Test!" Zweck: Test, ob Prg. die Anforderung grundsätzlich erfüllt. Führende sowie Leerzeichen nach und vor dem Satzzeichen '!' müssen entfernt werden.
Eingabewerte : " Das ist ein Text , welcher voller Fehler ist . " Erwartete Ausgabe : "Das ist ein Text, welcher voller Fehler ist." Zweck: Test, ob Prg. die Anforderung grundsätzlich erfüllt. Führende Leerzeichen, mehrere Leerzeichen zwischen den Wörtern, Leerzeichen vor und nach Satz- zeichen müssen entfernt werden.
Eingabewerte : " Fehlerhafter , ? ! . Text ! ! ! " Erwartete Ausgabe : "Fehlerhafter,?!. Text!!!" Zweck: Test mit mehreren aufeinander folgenden Satzzeichen.
Eingabewerte : "A" Erwartete Ausgabe : "A" Zweck: Test mit nur einem Zeichen.
Eingabewerte : " ! " Erwartete Ausgabe : "!" Zweck: Test mit nur einem Sonderzeichen. Eingabewerte : " A ! " Erwartete Ausgabe : "A!" Zweck: Test mit nur einem Zeichen und einem Sonderzeichen.
Eingabewerte: "" Erwartete Ausgbabe: Abbruch des Prg. Zweck: Test, ob Prg. richtig beendet wird.
Die Formel für die Multiplikation von zwei Matrizen kann einfach und lesbar mittels drei ineinander verschachtelte for-Schleifen realisiert werden, wobei die zwei ersten, die Zeile (i) und Spalte (k) des Ergebnisses zählen (wobei dies gleichzeitig die Zeile des zu lesenden Wertes aus der ersten Matrix sowie die Spalte des zu lesenden Wertes aus der zweiten Matrix ist) und die dritte (j) die Spalte des zu lesenden Wertes aus der ersten Matrix und die Zeile des zu lesenden Wertes aus der zweiten Matrix ist, entsprechend der Formel
c(i,k) = Summe von [a(i,j) * b(j,k)].
Der Einfachheit und der Lesbarkeit zugunsten wird die Aufgabenstellung objektorientiert realisiert, d.h. eine Klasse für die Matrix erstellt, welche die Werte sowie die darauf auszuführenden Methoden enthält. Das Einlesen und Ausgeben der Matrizen wird ebenfalls in Methoden dieser Klasse implementiert.
/** * * Softwareentwicklung I - Exercise 4/2. * Multiplication of two matrices. * In-source comments are followed by the described code. * * @author Daniel Brunthaler (0255054) * @version 1.0 * */ public class Matrix { // Values for this matrix. private float[][] value; /** * Constructor for Matrix. * @param value values of this matrix. */ public Matrix(float[][] value) { this.value = value; } /** * Amount of rows of this matrix. * @return amount of rows of this matrix. */ public int rows() { return value.length; } /** * Amount of columns of this matrix. * @return amount of columns of this matrix. */ public int columns() { return value[0].length; } /** * Certain value out of the matrix. * @param m row of value. * @param n column of value. * @return value according to given row and column. */ public float value(int m, int n) { return value[m][n]; } /** * Evaluates the maximum width of a number which occur in a certain column * of the matrix. * @param n column wherefor the width should be evaluated. * @return maximum width of a number which occur in the given column. */ public int columnWidth(int n) { int columnWidth = 0; int numberLength; for(int m = 0;m < rows();m++) { numberLength = String.valueOf(value[m][n]).length(); if(numberLength > columnWidth) { columnWidth = numberLength; } } return columnWidth; } /** * Read a Matrix from System.in. * @return Matrix read from System.in. */ public static Matrix readFromIO() { String promptDimensions = "Dimensionen (Zeilen Spalten) : "; String promptValues = "Werte (durch Leerzeichen getrennt) : "; IO.write(promptDimensions); int rows = IO.readInt(); // Check if reading the number was successfull. if (!IO.isOk()) return null; int columns = IO.readInt(); // Check if reading the number was successfull. if (!IO.isOk()) return null; float[][] value = new float[rows][columns]; IO.write(promptValues); for(int m = 0;m < rows;m++) { for(int n = 0;n < columns;n++) { value[m][n] = (float)IO.readDouble(); // Check if reading the number was successfull. if (!IO.isOk()) return null; } } return new Matrix(value); } /** * Prints matrix in a suitable format to System.out. */ public void printToIO() { int[] columnWidth = new int[columns()]; // Evaluate maximum column width for each colum. for(int n = 0;n < columns();n++) { columnWidth[n] = columnWidth(n); } for(int m = 0;m < rows();m++) { IO.write("| "); for(int n = 0;n < columns();n++){ // Evaluated maximum width is considered in the IO.write() method. IO.write(String.valueOf(value(m,n)),columnWidth[n] + 1); } IO.writeLn("|"); } } /** * Multiplies this matrix (a) with the given matrix b. * The element c(i,k) from the matrix product c = a * b is arised from the * scalar product of the row vector a(i) multiplied with the column vector * b(k). * (product) matrix c(i,k) = Sum of[matrix a(i,j) * matrix b(j,k)]. * The precondition for the multiplication of two matrices is, that the * amount of rows of matrix a is equal the amount of columns of matrix b. * @param b matrix which should this matrix multiplied with. * @return product of this matrix multiplied with matrix b. * @see http://miss.wu-wien.ac.at/~leydold/MOK/HTML/node17.html */ public Matrix multiply(Matrix b) { // for better reading only. Matrix a = this; Matrix product = null; // Check precondition for multiplication if amount of rows of matrix a // is equal the amount of columns of matrix b. If this is not complied // with, null is returned. if (!(a.columns() != b.rows())) { float[][] productValue = new float[a.rows()][b.columns()]; float value = 0; // c(i,k) = Sum[a(i,j) * b(j,k)]. for(int i = 0;i < a.rows();i++) { for(int k = 0;k < b.columns();k++) { value = 0; for(int j = 0;j < a.columns();j++) { value = value + a.value(i,j) * b.value(j,k); } productValue[i][k] = value; } } product = new Matrix(productValue); } return product; } public static void main(String[] args) { String msgInputError = "Fehlerhafte Eingabe! Programm wird beendet!"; String msgMultiplyError = "Matrizen erfuellen nicht die Vorraussetzungen, " + "um sie miteinander multiplizieren zu koennen " + "(Anz. Spalten der Matrix A = Anz. Zeilen der Matrix B)!"; IO.writeLn("Matrix A"); Matrix a = Matrix.readFromIO(); if (a == null) { IO.writeLn(msgInputError); System.exit(0); } a.printToIO(); IO.writeLn("\nMatrix B"); Matrix b = Matrix.readFromIO(); if (b == null) { IO.writeLn(msgInputError); System.exit(0); } b.printToIO(); // Multiply matrix a with b, the outcome is saved in c. Matrix c = a.multiply(b); IO.writeLn("\nMatrix C = Matrix A * Matrix B"); if (c == null) { IO.writeLn(msgMultiplyError); } else { c.printToIO(); } System.exit(0); } }
Die Eingabe wird analog der Eingabe im Prg. dargestellt, d.h. die Eingabe der Dimension erfolgt durch Zeile und Spalte durch mind. ein Leerzeichen getrennt, die Eingabe der Werte einer Matrix erfolgt von links oben nach rechts unten Zeile für Zeile, wobei die Werte ebenfalls durch mind. ein Leerzeichen getrennt werden. Komplizierte Matrizen wurden mit Mathematica 4.1 berechnet.
Eingabe (Dimension Matrix A): 2 2 Eingabe (Werte Matrix A): 1 2 3 4 Eingabe (Dimension Matrix B): 2 2 Eingabe (Werte Matrix B): 1 2 3 4 Erwartete Ausgabe: | 7 10 | | 15 22 | Zweck: Einfacher Test, ob das Prg. die Anforderung grundsätzlich erfüllt. Hardcopy:Eingabe (Dimension Matrix A): 3 4 Eingabe (Werte Matrix A): 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.1 11.11 0 Eingabe (Dimension Matrix B): 4 3 Eingabe (Werte Matrix B): 0 11.11 10.1 9.9 8.8 7.7 6.6 5.5 4.4 3.3 2.2 1.1 Erwartete Ausgabe (lt. Mathematica 4.1):
Zweck: Test, ob das Prg. kompliziertere Matrizen richtig ausmultipliziert. Hardcopy:
Eingabe (Dimension Matrix A): 2 1 Eingabe (Werte Matrix A): 111.1 222.2 Eingabe (Dimension Matrix B): 1 2 Eingabe (Werte Matrix B): 1 1 Erwartete Ausgabe: | 111.1 111.1 | | 222.2 222.2 | Zweck: Test mit zweidimensionalen Matrizen. Hardcopy:
Eingabe (Dimension Matrix A): 2 2 Eingabe (Werte Matrix A): 1 2 3 4 Eingabe (Dimension Matrix B): 1 1 Eingabe (Werte Matrix B): 2 1 Erwartete Ausgabe: Fehlermeldung, da Anzahl der Spalten der ersten Matrix nicht gleich Anzahl der Zeilen der zweiten Matrix sind. Zweck: Test des Fehlerfalles der nicht erfüllten Vorraussetzung für die Multiplikation. Hardcopy:
Eingabe (Dimension Matrix A): A Erwartete Ausgabe: Ausgabe einer Fehlermeldung und Abbruch des Prg. Zweck: Test Fehlerfalles nicht-numerischer Eingaben. Hardcopy: