[英]Read .txt file into 2D Array
有一些这样的主题,但这个问题有一个轻微的转折,使它与众不同。
我只关注一个更大问题的一半。 我相信你们很多人都知道幻方问题。
迅速的:
假设一个文件每行都有行和数字,如图所示。 编写一个程序,将信息读入 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;
}
这是我的(旧)代码,用于将文本文件中的信息读取到二维数组中:
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;
}
这是我正在阅读的文本文件。 它是一个 9x9 二维数组的形状,但程序必须容纳一个大小不明确的数组。
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
每行有两个空格是故意的。
在我陈述确切的问题之前,这是一个作业模板,因此方法声明和变量初始化是预先确定的。
我不确定该方法甚至从文件中正确创建了一个二维数组,因为我还不能运行它。 问题是由于某种原因,“矩阵”被初始化为 1 列和 2 行。 出于什么原因我不确定,但为了用文件中的数字填充数组,我需要创建一个二维数组,其维度等于一行中的值数。
我以前写过代码来创建一个新的二维数组
int[line.length()][line.length()]
但它创建了一个 36x36 数组,因为这是一行中有多少个字符。 我有一种感觉就像遍历第一行并让计数器跟踪每个由零分隔的数字序列一样简单。
对我来说,这个解决方案似乎太低效和太耗时,只是为了找到新数组的维度。 实现这一目标的最佳方法是什么? 不使用 ArrayLists,因为我必须在使用 ArrayLists 后重写这个程序。
我从您提供的文件中生成了以下二维数组:
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
该数组在读取文件的第一行时计算出正方形的大小。 这是非常动态的。 只要输入文件是一个完美的正方形,它就可以工作。 我没有进一步的错误处理。
这是一个简单的方法,它应该符合您的指导方针。
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 数组,以便您可以分别解析每个数字。 这样做之后,您就可以一次获得数组的全部长度,而无需麻烦的计数器。
首先,测试扫描仪的结果。 我不认为这些分隔符会起作用。 (顺便说一句,扫描仪的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);
}
这仅适用于问题的“阅读”部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.