मैं जावा में इस मैट्रिक्स को कैसे पार्स करूं?

Nov 10 2020

बस मज़े के लिए, मैंने तय किया कि मैं एक पायथन कार्यक्रम लिखना चाहता हूं जो कि NumPy लाइब्रेरी का उपयोग किए बिना मैट्रिसेस (संख्या डेटा के आयताकार संग्रह) पर गणितीय संचालन करता है, जो कि विशेष रूप से मैट्रिक्स गणित (रैखिक बीजगणित) के लिए ब्यूटिल्ट था। मैंने पायथन में उस कार्यक्रम को पूरा कर लिया है, लेकिन तब से, मैंने फैसला किया कि मैं इसे जावा कोड में बदलने की कोशिश करना चाहता हूं। चूंकि पायथन जावा की तरह कड़ाई से टाइप नहीं किया गया है, इसलिए मेरा मुद्दा वर्तमान में उपयोगकर्ता के स्ट्रिंग मैट्रिक्स इनपुट को फॉर्म में दर्ज कर रहा है x x x, x x x, x x x, ..., जहां प्रत्येक नंबर को एक स्थान से अलग किया जाता है, और प्रत्येक पंक्ति को अल्पविराम और एक स्थान से अलग किया जाता है। मुझे उस में पार्स करना है[[x, x, x], [x, x, x], [x, x, x], [...]]

मैंने एक अलग फ़ंक्शन बनाया है जो double[][] matrixउपयोगकर्ता को इनपुट लौटाएगा और प्राप्त करेगा, लेकिन परीक्षण के लिए मैंने इसकी वापसी प्रकार को छोड़ दिया है और इसे [[1, 2, 3], [4, 5, 6], [7, 8, 9]]फॉर्म में एक डिफ़ॉल्ट मैट्रिक्स दिया है"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");
    }

इस परीक्षण कोड में, मैं चाहता हूं कि यह [[1, 2, 3], [4, 5, 6], [7, 8, 9]]3 बार प्रिंट हो , लेकिन यह [1 2 3, 4 5 6, 7 8 9]3 बार प्रिंट करता है। मैं क्या खो रहा हूँ?

जवाब

1 Aman Nov 10 2020 at 18:08

आपका आउटपुट 2D सरणी है, इसलिए पार्सिंग को इस तरह किया जाना चाहिए।

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

aString.split(" ")कॉल परिणाम है, जो आप अनदेखा कर रहे की एक सरणी देता है, लेकिन मूल सरणी संशोधित नहीं करता है । आपको कहीं न कहीं नव-पंक्तिबद्ध पंक्ति को संग्रहीत करने के लिए इसके परिणाम का उपयोग करने की आवश्यकता है:

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

यदि आप डबल [] [] के साथ संतुष्ट हैं तो एक लाइनर संभव है

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);
}

यह मूल रूप से एक सीएसवी प्रारूप है, इसलिए कॉमन्स-सीएसवी भी कुछ बदसूरत ट्विक्स के साथ पार्सिंग का काम करता है:

List<CSVRecord> rows = CSVFormat.DEFAULT.withDelimiter(' ')
            .parse(new StringReader(matrix.replace(", ", "\n")))
            .getRecords();

कुछ लोग सोचते हैं, कि यह सब वस्तु-, विभाजित- और धारा- और पुस्तकालय सामान वास्तव में लंगड़ा है और इसकी पूरी तरह से 1 व्यक्ति मोड में पूरी तरह से इस कार्यक्षमता को बनाने के लिए बहुत अच्छा है, वास्तव में निम्न-स्तरीय पुराने स्कूल, स्कैनर, पार्सर, क्या नहीं, में char[]केवल उपयोग करने की आदरणीय, सदियों पुरानी तपस्वी परंपरा । यह संभव है , और इस तरह से यह भी अनावश्यक कोड शुरू किए बिना एक कारक 70 से एलओसी बढ़ाने के लिए संभव है , ठीक है ... ज्यादा नहीं, इकाई परीक्षण गिना नहीं।