将.txt文件读入2D数组

这里有一些主题,但这个问题略有不同,使其与众不同。

我只专注于一个更大问题的一半。 我相信很多人都知道这个神奇的方块问题。

提示:
假设每行上都有行和数字的文件,如所示的正方形。 编写一个程序,将信息读入intS的二维数组。 程序应确定矩阵是否是魔方。

工作方案:

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

这是我(旧)代码,用于将文本文件中的信息读取到2D数组中:

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

这是我正在阅读的文本文件。 它的形状为9×9 2Darrays,但程序必须容纳一个模糊大小的数组。

  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 

有目的地每行都有两个空格。

在我陈述确切问题之前,这是一个家庭作业模板,因此预先确定了方法声明和变量初始化。

我并不认为该方法甚至可以正确地从文件中创建2D数组,因为我还无法运行它。 问题在于,由于某种原因,“矩阵”被初始化为1列和2行。 出于什么原因我不确定,但为了用文件中的数字填充数组,我需要创建一个尺寸等于一行中数值的二维数组。

我之前编写过代码来创建一个新的2D数组

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

但它创建了一个36x36arrays,因为这是一行中有多少个别字符。 我感觉它就像循环第一行一样简单,并且计数器跟踪由零分隔的每个数字序列。

对我来说,这个解决方案似乎效率太低,而且只是为了找到新arrays的尺寸而耗费时间。 实现这一目标的最佳方法是什么? 不使用ArrayLists,因为我必须在使用ArrayLists后重写此程序。

我从您提供的文件中生成了以下2D数组:

  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 

当数组读取文件的第一行时,该数组会计算出正方形的大小。 这非常有活力。 只要输入文件是完美的正方形,它的工作原理。 我没有进一步的error handling。

这是一个简单的方法,应该遵循您的指导方针。

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

这种方法更加精细和优化。

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

你很接近,但改变你的while循环看起来如下所示:

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

为了让自己更轻松,您可以做出的最大改变是逐行获取数字。 对于每行,您可以很容易地将其拆分为String数组,以便您可以分别解析每个数字。 这样做你就可以一次性获得数组的全长,而不必有麻烦的计数器。

首先,测试扫描仪结果。 我不认为那些分隔符会起作用。 (BTW,Scanner的nextInt()方法很方便。)

如果您可以假设输入是方形矩阵,则扫描第一行将显示它包含的整数数量。 然后你可以(重新)分配数组。 然后处理所有行,包括您已扫描的第一行。

然后你可以设置matrix = new int[n][n];

使用Java 8和它的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); } 

这只是问题的“阅读”部分。