Wie analysiere ich diese Matrix in Java?

Nov 10 2020

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

1 Aman Nov 10 2020 at 18:08

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;
}
2 tucuxi Nov 10 2020 at 18:03

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;
}
NikolaiDmitriev Nov 10 2020 at 23:16

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.