Wie analysiere ich diese Matrix in Java?
Nur zum Spaß habe ich beschlossen, ein Python-Programm zu schreiben, das mathematische Operationen an Matrizen (rechteckigen Sammlungen von Zahlendaten) ausführt, ohne die NumPy-Bibliothek zu verwenden, die speziell für die Matrixmathematik (Lineare Algebra) entwickelt wurde. Ich habe dieses Programm in Python abgeschlossen, aber seitdem habe ich beschlossen, es in Java-Code umzuwandeln. Da Python nicht wie Java streng typisiert ist, analysiert mein Problem derzeit die Eingabe der String-Matrix des Benutzers in dem Formular x x x, x x x, x x x, ..., wobei jede Zahl durch ein Leerzeichen und jede Zeile durch ein Komma und ein Leerzeichen getrennt ist. Ich muss das analysieren[[x, x, x], [x, x, x], [x, x, x], [...]]
Ich habe eine separate Funktion erstellt, die das zurückgibt double[][] matrixund Benutzereingaben empfängt, aber zum Testen habe ich den Rückgabetyp ungültig gelassen und ihm eine Standardmatrix von [[1, 2, 3], [4, 5, 6], [7, 8, 9]]im Formular gegeben"1 2 3, 4 5 6, 7 8 9"
// Takes text input; transforms it into array of arrays (matrix)
// parse 'x x x, x x x, ...' into [[x, x, x], [x, x, x], [...]]
private static void parseMatrix(String matrix) {
String[] partMat = matrix.strip().split(", "); // Separates each row (one array results)
for(int i = 0; i < partMat.length; i++) { // Supposed to create arrays out of rows (multiple arrays result)
partMat[i].split(" ");
System.out.println(Arrays.toString(partMat));
}
}
public static void main(String[] args) {
parseMatrix("1 2 3, 4 5 6, 7 8 9");
}
In diesem Testcode soll er [[1, 2, 3], [4, 5, 6], [7, 8, 9]]dreimal gedruckt werden , aber er wird [1 2 3, 4 5 6, 7 8 9]dreimal gedruckt . Was vermisse ich?
Antworten
Ihre Ausgabe ist ein 2D-Array, daher sollte die Analyse als solche durchgeführt werden.
private static double[][] parseMatrix(String matrix) {
String[] parentMat = matrix.split(", ");
double[][] childMat = new double[parentMat.length][];
for (int i = 0; i < parentMat.length; i++) {
String[] child = parentMat[i].split(" ");
childMat[i] = new double[child.length];
for (int j = 0; j < child.length; j++) {
childMat[i][j] = Double.parseDouble(child[j]);
}
}
System.out.print(Arrays.deepToString(childMat)); //[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]
return childMat;
}
Der aString.split(" ")Aufruf gibt ein Array von Ergebnissen zurück, das Sie ignorieren, das ursprüngliche Array jedoch nicht ändern . Sie müssen das Ergebnis verwenden, um die neu analysierte Zeile irgendwo zu speichern:
private static double[][] parseMatrix(String matrix) {
String[] partMat = matrix.strip().split(", ");
double[][] rows = new double[partMat.length][];
for(int i = 0; i < partMat.length; i++) {
String[] row = partMat[i].split(" "); // <-- store result
System.out.println(Arrays.toString(row));
// will fail unless you use Double.valueOf to parse each element
// rows[i] = row;
}
return rows;
}
Wenn Sie mit Double [] [] zufrieden sind, ist ein Einzeiler möglich
private static Double[][] parseMatrix(String matrix) {
return Stream.of(matrix.split(", "))
.map(row -> Stream.of(row.split(" ")).map(Double::valueOf).toArray(Double[]::new))
.toArray(Double[][]::new);
}
Es ist im Grunde ein CSV-Format, daher erledigt commons-csv mit ein paar hässlichen Änderungen auch den Parsing-Job:
List<CSVRecord> rows = CSVFormat.DEFAULT.withDelimiter(' ')
.parse(new StringReader(matrix.replace(", ", "\n")))
.getRecords();
Einige denken, dass all dieses Objekt-, Split- und Stream- und Bibliotheksmaterial wirklich lahm ist und es viel cooler ist, diese Funktionalität vollständig im 1st-Person-Modus zu erstellen, wirklich Low-Level-Old-School, Scanner, Parser, was nicht die ehrwürdige, jahrhundertealte asketische Tradition, char[]nur zu benutzen . Es ist möglich , und auf diese Weise ist es auch möglich, die LoC um den Faktor 70 zu erhöhen, ohne unnötigen Code einzuführen, na ja ... nicht viel, Unit-Tests werden nicht gezählt.