这里有一些主题,但这个问题略有不同,使其与众不同。
我只关注一个更大问题的一半。我相信很多人都知道这个神奇的方块问题。
提示:
假设每行上都有行和数字的文件,如所示的正方形。编写一个程序,将信息读入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;
}
这是我正在阅读的文本文件。它采用9x9 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
有意地每行进行两个空格。
在我说出确切问题之前,这是一个家庭作业模板,因此预先确定了方法声明和变量初始化。
我并不认为该方法甚至可以正确地从文件中创建2D数组,因为我还无法运行它。问题在于,由于某种原因,“矩阵”被初始化为1列和2行。出于什么原因我不确定,但为了用文件中的数字填充数组,我需要创建一个尺寸等于一行中数值的二维数组。
我以前写过代码来创建一个新的2D数组
int[line.length()][line.length()]
但它创建了一个36x36阵列,因为这是一行中有多少个别字符。我感觉它就像循环第一行一样简单,并且计数器跟踪由零分隔的每个数字序列。
对我来说,这个解决方案似乎效率太低,而且只是为了找到新阵列的尺寸而耗费时间。实现这一目标的最佳方法是什么?不使用ArrayLists,因为我必须在使用ArrayLists后重写此程序。
答案 0 :(得分:6)
我从您提供的文件中生成了以下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
当数组读取文件的第一行时,数字会计算出正方形的大小。这非常有活力。只要输入文件是完美的正方形,它的工作原理。我没有进一步的错误处理。
这是一个简单的方法,应该遵循您的指导方针。
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());
}
}
答案 1 :(得分:1)
你已经关闭,但是将你的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数组,以便您可以分别解析每个数字。这样做就可以一次性获得数组的全长,而不必有麻烦的计数器。
答案 2 :(得分:0)
首先,测试扫描仪结果。我不认为这些分隔符会起作用。 (顺便说一下,扫描仪的nextInt()
方法很方便。)
如果您可以假设输入是方形矩阵,则扫描第一行将显示它包含的整数数量。然后你可以(重新)分配数组。然后处理所有行,包括您已扫描的第一行。
然后您可以设置matrix = new int[n][n];
答案 3 :(得分:0)
使用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);
}
这只是问题的“阅读”部分。