2014-03-04 155 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); 
    } 

這僅僅是問題的 '閱讀' 部分。