Lesen Sie die .txt-Datei in das 2D-Array

Es gibt ein paar dieser Themen da draußen, aber dieses Problem hat eine kleine Wendung, die es anders macht.

Ich konzentriere mich nur auf die Hälfte eines größeren Problems. Ich bin mir sicher, dass viele von Ihnen das magische Quadratproblem kennen.

Prompt:
Nehmen Sie eine Datei mit Linien und Zahlen in jeder Zeile wie das gezeigte Quadrat an. Schreiben Sie ein Programm, das Informationen in ein zweidimensionales Array von IntS liest. Das Programm sollte bestimmen, ob die Matrix ein magisches Quadrat ist oder nicht.

Arbeitslösung:

public static int[][] create2DIntMatrixFromFile(String filename) throws Exception { int[][] matrix = {{1}, {2}}; File inFile = new File(filename); Scanner in = new Scanner(inFile); int intLength = 0; String[] length = in.nextLine().trim().split("\\s+"); for (int i = 0; i < length.length; i++) { intLength++; } in.close(); matrix = new int[intLength][intLength]; in = new Scanner(inFile); int lineCount = 0; while (in.hasNextLine()) { String[] currentLine = in.nextLine().trim().split("\\s+"); for (int i = 0; i < currentLine.length; i++) { matrix[lineCount][i] = Integer.parseInt(currentLine[i]); } lineCount++; } return matrix; } public static boolean isMagicSquare(int[][] square) { return false; } 

Hier ist mein (alter) Code zum Lesen von Informationen aus einer Textdatei in ein 2D-Array:

 public static int[][] create2DIntMatrixFromFile(String filename) throws Exception { int[][] matrix = {{1}, {2}}; File inFile = new File(filename); Scanner in = new Scanner(inFile); in.useDelimiter("[/n]"); String line = ""; int lineCount = 0; while (in.hasNextLine()) { line = in.nextLine().trim(); Scanner lineIn = new Scanner(line); lineIn.useDelimiter(""); for (int i = 0; lineIn.hasNext(); i++) { matrix[lineCount][i] = Integer.parseInt(lineIn.next()); lineIn.next(); } lineCount++; } return matrix; } public static boolean isMagicSquare(int[][] square) { return false; } 

Und hier ist die Textdatei, aus der ich lese. Es hat die Form eines 9×9-2D-Arrays, aber das Programm muss ein Array mehrdeutiger Größe aufnehmen.

  37 48 59 70 81 2 13 24 35 36 38 49 60 71 73 3 14 25 26 28 39 50 61 72 74 4 15 16 27 29 40 51 62 64 75 5 6 17 19 30 41 52 63 65 76 77 7 18 20 31 42 53 55 66 67 78 8 10 21 32 43 54 56 57 68 79 9 11 22 33 44 46 47 58 69 80 1 12 23 34 45 

Es gibt zwei Räume, die absichtlich jede Linie durchlaufen.

Bevor ich das genaue Problem darlege, handelt es sich um eine Hausaufgabenvorlage, so dass die Methodendeklaration und Variableninitialisierung vorher festgelegt wurde.

Ich bin nicht davon überzeugt, dass die Methode sogar ein 2D-Array aus der Datei korrekt erstellt, weil ich es noch nicht ausführen kann. Das Problem ist, dass “Matrix” aus irgendeinem Grund mit 1 Spalte und 2 Zeilen initialisiert wurde. Aus welchem ​​Grund bin ich nicht sicher, aber um ein Array mit den Zahlen aus der Datei zu füllen, muss ich ein 2D-Array mit Dimensionen erstellen, die der Anzahl der Werte in einer Zeile entsprechen.

Ich hatte zuvor Code geschrieben, um ein neues 2D-Array zu erstellen

 int[line.length()][line.length()] 

aber es hat ein Array 36×36 erstellt, weil sich so viele einzelne Zeichen in einer Zeile befinden. Ich habe das Gefühl, dass es so einfach ist, die erste Zeile zu durchlaufen und einen Zähler zu haben, der jede durch eine Null getrennte Zahlenfolge verfolgt.

Diese Lösung scheint mir zu ineffizient und zeitaufwendig zu sein, nur um die Dimensionen des neuen Arrays zu finden. Was ist der beste Weg, dies zu erreichen? Ohne ArrayLists zu verwenden, da ich dieses Programm nach der Verwendung von ArrayLists neu schreiben muss.

Ich habe das folgende 2D-Array aus der von Ihnen bereitgestellten Datei erstellt:

  37 | 48 | 59 | 70 | 81 | 2 | 13 | 24 | 35 ----+----+----+----+----+----+----+----+---- 36 | 38 | 49 | 60 | 71 | 73 | 3 | 14 | 25 ----+----+----+----+----+----+----+----+---- 26 | 28 | 39 | 50 | 61 | 72 | 74 | 4 | 15 ----+----+----+----+----+----+----+----+---- 16 | 27 | 29 | 40 | 51 | 62 | 64 | 75 | 5 ----+----+----+----+----+----+----+----+---- 6 | 17 | 19 | 30 | 41 | 52 | 63 | 65 | 76 ----+----+----+----+----+----+----+----+---- 77 | 7 | 18 | 20 | 31 | 42 | 53 | 55 | 66 ----+----+----+----+----+----+----+----+---- 67 | 78 | 8 | 10 | 21 | 32 | 43 | 54 | 56 ----+----+----+----+----+----+----+----+---- 57 | 68 | 79 | 9 | 11 | 22 | 33 | 44 | 46 ----+----+----+----+----+----+----+----+---- 47 | 58 | 69 | 80 | 1 | 12 | 23 | 34 | 45 

Das Array berechnet die Größe des Quadrats, wenn es die erste Zeile der Datei liest. Das ist sehr dynamisch. Es funktioniert, solange die Eingabedatei ein perfektes Quadrat ist. Ich habe keine weitere Fehlerbehandlung.

Hier ist ein einfacher Ansatz, der sich an Ihre Richtlinien halten sollte.

 import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; public class ReadMagicSquare { public static int[][] create2DIntMatrixFromFile(String filename) throws Exception { int[][] matrix = null; // If included in an Eclipse project. InputStream stream = ClassLoader.getSystemResourceAsStream(filename); BufferedReader buffer = new BufferedReader(new InputStreamReader(stream)); // If in the same directory - Probably in your case... // Just comment out the 2 lines above this and uncomment the line // that follows. //BufferedReader buffer = new BufferedReader(new FileReader(filename)); String line; int row = 0; int size = 0; while ((line = buffer.readLine()) != null) { String[] vals = line.trim().split("\\s+"); // Lazy instantiation. if (matrix == null) { size = vals.length; matrix = new int[size][size]; } for (int col = 0; col < size; col++) { matrix[row][col] = Integer.parseInt(vals[col]); } row++; } return matrix; } public static void printMatrix(int[][] matrix) { String str = ""; int size = matrix.length; if (matrix != null) { for (int row = 0; row < size; row++) { str += " "; for (int col = 0; col < size; col++) { str += String.format("%2d", matrix[row][col]); if (col < size - 1) { str += " | "; } } if (row < size - 1) { str += "\n"; for (int col = 0; col < size; col++) { for (int i = 0; i < 4; i++) { str += "-"; } if (col < size - 1) { str += "+"; } } str += "\n"; } else { str += "\n"; } } } System.out.println(str); } public static void main(String[] args) { int[][] matrix = null; try { matrix = create2DIntMatrixFromFile("square.txt"); } catch (Exception e) { e.printStackTrace(); } printMatrix(matrix); } } 

Dieser Ansatz wird verfeinert und optimiert.

 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class ReadMagicSquare { private int[][] matrix; private int size = -1; private int log10 = 0; private String numberFormat; public ReadMagicSquare(String filename) { try { readFile(filename); } catch (IOException e) { e.printStackTrace(); } } public void readFile(String filename) throws IOException { // If included in an Eclipse project. InputStream stream = ClassLoader.getSystemResourceAsStream(filename); BufferedReader buffer = new BufferedReader(new InputStreamReader(stream)); // If in the same directory - Probably in your case... // Just comment out the 2 lines above this and uncomment the line // that follows. //BufferedReader buffer = new BufferedReader(new FileReader(filename)); String line; int row = 0; while ((line = buffer.readLine()) != null) { String[] vals = line.trim().split("\\s+"); // Lazy instantiation. if (matrix == null) { size = vals.length; matrix = new int[size][size]; log10 = (int) Math.floor(Math.log10(size * size)) + 1; numberFormat = String.format("%%%dd", log10); } for (int col = 0; col < size; col++) { matrix[row][col] = Integer.parseInt(vals[col]); } row++; } } @Override public String toString() { StringBuffer buff = new StringBuffer(); if (matrix != null) { for (int row = 0; row < size; row++) { buff.append(" "); for (int col = 0; col < size; col++) { buff.append(String.format(numberFormat, matrix[row][col])); if (col < size - 1) { buff.append(" | "); } } if (row < size - 1) { buff.append("\n"); for (int col = 0; col < size; col++) { for (int i = 0; i <= log10 + 1; i++) { buff.append("-"); } if (col < size - 1) { buff.append("+"); } } buff.append("\n"); } else { buff.append("\n"); } } } return buff.toString(); } public static void main(String[] args) { ReadMagicSquare square = new ReadMagicSquare("square.txt"); System.out.println(square.toString()); } } 

Sie sind in der Nähe, aber ändern Sie Ihre while-Schleife so, dass sie wie folgt aussieht:

 while (in.hasNextLine()) { Scanner lineIn = new Scanner(line); //The initial case - this first line is used to determine the size of the array if(lineIn.hasNext()) { //Create a String array by splitting by spaces String[] s = lineIn.nextLine().split(" "); //Reinitialize the array to hold all of your subarrays matrix = new int[s.length]; for (int i = 0; i < s.length; i++) { //Reinitialize each subarray to hold the numbers matrix[i] = new int[i]; //Finally, parse your data from the String array matrix[0][i] = Integer.parseInt(s[i]); } } //Repeat the steps now that all of your arrays have been initialized for (int j = 1; j < matrix.length; j++) { String[] s = lineIn.nextLine().split(" "); for (int i = 0; i < s.length; i++) { matrix[j][i] = Integer.parseInt(s[i]); } } } 

Die größte Veränderung, die Sie machen können, um sich dies zu erleichtern, ist, Ihre Zahlen Zeile für Zeile zu bekommen. Mit jeder Zeile, die Sie erhalten, ist es einfach, sie in ein String-Array zu zerlegen, so dass Sie jede Zahl einzeln analysieren können. Auf diese Weise können Sie dann die gesamte Länge des Arrays auf einmal abrufen, ohne lästige Zähler haben zu müssen.

Testen Sie zuerst die Scanner-Ergebnisse. Ich glaube nicht, dass diese Trennzeichen funktionieren. (BTW, nextInt() -Methode ist praktisch.)

Wenn Sie davon ausgehen können, dass die Eingabe eine quadratische Matrix ist, wird beim Scannen der ersten Zeile angezeigt, wie viele Ganzzahlen enthalten sind. Dann können Sie die Arrays (neu) zuordnen. Verarbeiten Sie dann alle Zeilen, einschließlich der ersten Zeile, die Sie bereits gescannt haben.

Dann können Sie matrix = new int[n][n];

Mit Java 8 und seinen Streams :

  static public int[][] create2DIntMatrixFromFile(Path path) throws IOException { return Files.lines(path) .map((l)->l.trim().split("\\s+")) .map((sa)->Stream.of(sa).mapToInt(Integer::parseInt).toArray()) .toArray(int[][]::new); } 

Dies ist nur für den “Lese” -Teil der Frage.