2014-03-04 103 views
5

这里有几个主题,但是这个问题稍有不同,会使它不同。将.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; 
} 

下面是用于读取文本文件信息到一个二维数组我的(旧)代码:

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后重写此程序。

+0

要获得给定行上的数字,您可以简单地调用'line.split(“”);'。 – ggmathur

回答

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

,你可以做的最大的变化,使这更容易对自己是让您的数字线由行。对于每一行,您都可以很容易地将其分割成一个字符串数组,以便您可以分别解析每个数字。这样做,您可以一次性获得阵列的全部长度,而无需使用麻烦的计数器。

+0

我已经实现了这个循环,但是我在'.nextLine()'上得到了“没有这样的元素”的错误,我不确定它到达文件末尾的哪一点。 – BimmerM3

0

首先,测试扫描仪结果。我不认为这些分隔符会起作用。 (顺便说一句,扫描仪的nextInt()方法很方便。)

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

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

5

我公司生产从你提供的文件中的以下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()); 
    } 
} 
+0

我明白这是解决问题的唯一答案,但我们从来没有被引入缓冲区,还没有用辅助方法编写类。我知道我会产生正确的答案,但我认为我需要它以更基本的方式完成。 – BimmerM3

+0

如果输入的列(9)多于行(1),该怎么办?你需要用1行和1列初始化矩阵,并最终以arrayindexoutofbound异常结束。 –

+0

你读过我说过的吗? “这是非常有活力的,***只要输入文件是一个完美的方块,它就可以工作。***我没有进一步的错误处理。” –

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

这仅仅是问题的 '阅读' 部分。