2012-11-14 109 views
0

這是一個很長的文本。從一個文本文件中讀取兩個矩陣

我有一個很奇怪的問題。我需要從文本文件中讀取兩個矩陣,將它們相乘,然後打印出結果。這很容易。問題是,包含矩陣的文件看起來像這樣:

1 2 1 2 3 
3 4 4 5 6 
5 6 
7 8 

這個瘋狂的事情是如何工作如下(僅供參考,你可以跳過這一部分):

  1. 讀下來第一列。一旦你打空白或文件的結尾,你的FIRST矩陣中有多少行。

  2. 按行逐行計算整數的數量。一旦這個數字下降,你知道你的第二個矩陣有多少行。如果第一個矩陣比文件「短」,那麼這一步是不必要的,因爲第二個矩陣只是文件中的行數。由於乘法需要矩陣的列數與矩陣2的行數相同([3x6 * 6x4]有效,[3x6 * 5x4]不是),因此通過知道矩陣1中的列數,我們可以找到矩陣2中的行數,反之亦然。

我需要找到任一值。

所以從該文件矩陣之一將是

1 2 
3 4 
5 6 
7 8 

兩個是

1 2 3 
4 5 6 

所以,你會覺得你可以只算一列中的行和列的數量最後一行找到一切,但有時文件看起來像這樣:

1 2 1 2 3 
3 4 4 5 6 
     7 8 

所以我只需要一些公司根據左下角是int還是空白來處理雜耍。我正在考慮將整個文件讀入一個2D數組並從那裏進行操作。

因此,這裏有我的正式問題:

我需要將文件的每一個字符分別進行閱讀,無論是int或空格,這樣我就可以建立一個忠實的數組[] []。做這件事的最好方法是什麼?我曾嘗試掃描儀,StringTokenizer,FileInputStream,BufferedInputStream,Reader和FileReader,但他們都沒有給我一個簡單的字符char。其次,關於將統一數組[] []中的矩陣拆分爲兩個更小的數組[] [] s的任何建議?

+0

在哪裏做這些文本文件都來自? –

+0

它們來自JUnit測試,因此它們是不可變的。 –

+0

@ThorbjørnRavnAndersen我相信如果我們提供了最可能的答案給你的問題,版主會介入。 –

回答

0

您應該能夠使用FileInputStream逐個字符地讀入文件。

請注意,read()方法在EOF處返回-1。否則將返回的值轉換爲char。

+0

如果我爲該文件創建一個FileInputStream並使用「(char)FileIn.read()」,我仍然可以獲得字節值「1 2 1 2 3」變成「49,32,49,32,50」(或其他),這是雙奇數,因爲那些不是字符...是你的意思嗎? –

+0

哦,看,我是現在我可以讀取每個字符 –

0

只能逐行閱讀文本文件。 因此讀一行,使用String分割它。拆分(「」)並將結果數據填入鏈接列表中,鏈接列表保存Integer.Keep的鏈接列表記住,您必須跟蹤分割數據在輸入字符串中的位置,以記住開始位置第二種情況下的第二個矩陣。

LinkedList<LinkedList<Integer>> 

讀取文件中的所有行之後,你有「最高」矩陣的行完整的號碼,你可以把第一個矩陣的數據在陣列中,而在同一個點下降相同的數據來自鏈表(Lisp.pop())的時間。

  • 我無法想象,讀入數組的數組有可能在一個運行,因爲你不知道事先的行數通過文件讀取時間。因此你需要使用一個集合類。
  • 我建議使用LinkedList,因爲與使用由數組支持的集合相比,刪除wit pop是非常高效和快速的。
  • LinkedList也可用於矩陣的高效乘法,同時通過列表。
+0

不幸的是,我不能使用任何分隔符方法,因爲它會跳過的一些空格是「重要的」。我使用常規數組,因爲到那時我將知道文件的尺寸,並且在我插入數組[] []之後,我可以輕鬆確定這兩個矩陣的尺寸。 –

0

那麼對兩個矩陣來說,最大行數是行數,最大列數是行的長度+ 1/2,不包括用於行結尾的任何行如CRLF)

當你通過對信息的這兩個位的文件掃描, 又找了第一個或最後一個字符是一個空間,如果沒有跳過 如果第一沿,直到你碰到第二個數組 掃描如果最後一個,掃描回來,直到碰到第一個 其他可能性當然是兩個具有相同尺寸的陣列。

武裝與信息的那些位,您可以創建兩個數組,然後再次掃描文件,並在適當的地方插槽值。

這是一個有點殘酷,但卻很有效並易於測試。

+0

我在想類似的事情。如果掃描最右邊的列,那麼行數就是第二個矩陣中的行數和第一個中的列數。然後,如果從文件寬度中減去該數字,則可以找到矩陣2中的列數。然後,您可以只掃描第一列中的行數,以計算矩陣1中的行數。然後,獲得所需的所有數據。我只需要這樣做的最簡單的方法。 –

+0

如果是我,我只是讀了每一行,一次傳遞出來,另一個文件組成另一個文件來挖掘數字。除非有大量的大量文件,否則就簡單/優雅的路線而言,看不出任何過於巧妙的點。得到它的工作,然後如果你有找到最聰明的方式的理由,至少你有什麼比較它。 –

0

我建議在4個階段的分裂問題:閱讀文本,建立字符串單元陣列,建立整數矩陣陣列,做矩陣的乘積:

import java.util.ArrayList; 
import java.util.List; 

public class MatrixMul { 
    static String[][] text2StrMatrices(String[] text) { 
     List<String[]> w = new ArrayList<>(12); 
     for(String line : text) 
     { 
     List<String> l = new ArrayList<>(line.length()/2); 
     for(int i = 0; i < line.length(); ++i) 
     { 
      char c = line.charAt(i); 
      if(c == ' ') 
      { 
       l.add(" "); 
       ++i; 
      } 
      else { 
       String num = ""; 
       while(c != ' ' && i < line.length()) { 
        num += c; 
        if(++i < line.length()) { 
        c = line.charAt(i); 
        } 
       } 
       l.add(num); 
      } 
     } 
     w.add(l.toArray(new String[l.size()])); 
     } 
     return w.toArray(new String[w.size()][]); 
    } 

    static int countValues(String[] row) 
    { 
     int count = 0; 
     for(String value : row) { 
     if(value.trim().length() > 0) { 
      ++count; 
     } 
     } 
     return count; 
    } 

    static int[][][] strMatrices2IntegerMatrices(String[][] str) { 
     int count = str[0].length; 
     int row = 0; 
     while(row < str.length && count == countValues(str[row])) { 
     ++row; 
     } 
     int first = -1; 
     for(int i = 0; first == -1 && i < str[row].length; ++i) { 
     if(str[row][i].trim().length() > 0) { 
      first = i; 
     } 
     } 
     int columns = 0; 
     if(first > 0) { 
     columns = first; 
     } 
     else { 
     columns = countValues(str[row]); 
     } 
     List<int[]> w = new ArrayList<>(4); 
     for(int r = 0; r < (first == 0 ? str.length : row); ++r) 
     { 
     int[] aRow = new int[columns]; 
     for(int c = 0; c < columns; ++c) { 
      aRow[c] = Integer.parseInt(str[r][c]); 
     } 
     w.add(aRow); 
     } 
     int[][][] result = new int[2][][]; 
     result[0] = w.toArray(new int[w.size()][]); 
     w.clear(); 
     for(int r = 0; r < (first == 0 ? row : str.length); ++r) 
     { 
     int[] aRow = new int[str[0].length-columns]; 
     for(int c = columns; c < str[r].length; ++c) { 
      aRow[c-columns] = Integer.parseInt(str[r][c]); 
     } 
     w.add(aRow); 
     } 
     result[1] = w.toArray(new int[w.size()][]); 
     return result; 
    } 

    private static int[][] matricesProduct(int[][] a, int[][] b) 
    { 
     int m = a.length; 
     int n = b[0].length; 
     int p = b.length; 
     assert (m == n) || (a[0].length == p): "Incompatible dimensions"; 
     int[][] prod = null; 
     if(p > -1) { 
     prod = new int[m][n]; 
     for(int i = 0; i < m; ++i) { 
      for(int j = 0; j < n; ++j) { 
       for(int k = 0; k < p; ++k) { 
        prod[i][j] += a[i][k] * b[k][j]; 
       } 
      } 
     } 
     } 
     return prod; 
    } 

    static void test(
     String  title, 
     String[] text, 
     String[][] expectedStrMatrices, 
     int[][][] expectedMatrices, 
     int[][] expectedProduct) 
    { 
     System.out.println(title); 
     final String[][] observedStrMatrices = text2StrMatrices(text); 
     assert compare(expectedStrMatrices, observedStrMatrices): 
     "text2StrMatrices() failed"; 
     final int[][][] observedMatrices = 
     strMatrices2IntegerMatrices(observedStrMatrices); 
     assert compare(expectedMatrices, observedMatrices): 
     "strMatrices2IntegerMatrices() failed"; 
     final int[][] observedProduct = 
     matricesProduct(observedMatrices[0], observedMatrices[1]); 
     displayMatrix(observedProduct); 
     assert compare(expectedProduct, observedProduct): 
     "matricesProduct() failed"; 
    } 

    public static void main(String[] args) { 
     final String[] text1 = { 
     "1 2 1 2 3", 
     "3 4 4 5 6", 
     "5 6", 
     "7 8", 
     }; 
     final String[][] expectedStrMatrices1 = { 
     { "1", "2", "1", "2", "3" }, 
     { "3", "4", "4", "5", "6" }, 
     { "5", "6" }, 
     { "7", "8" }, 
     }; 
     final int[][][] expectedMatrices1 = {{ 
      { 1, 2 }, 
      { 3, 4 }, 
      { 5, 6 }, 
      { 7, 8 }, 
     },{ 
      { 1, 2, 3 }, 
      { 4, 5, 6 }, 
     }}; 
     final int[][] expectedProduct1 = { 
     { 9, 12, 15 }, 
     { 19, 26, 33 }, 
     { 29, 40, 51 }, 
     { 39, 54, 69 }, 
     }; 
     test("First test case", text1, expectedStrMatrices1, expectedMatrices1, expectedProduct1); 
     final String[] text2 = { 
     "1 2 1 2 3", 
     "3 4 4 5 6", 
     "  7 8", 
     }; 
     final String[][] expectedStrMatrices2 = { 
     { "1", "2", "1", "2", "3" }, 
     { "3", "4", "4", "5", "6" }, 
     { " ", " ", " ", "7", "8" }, 
     }; 
     final int[][][] expectedMatrices2 = {{ 
      { 1, 2, 1 }, 
      { 3, 4, 4 }, 
     },{ 
      { 2, 3 }, 
      { 5, 6 }, 
      { 7, 8 }, 
     }}; 
     final int[][] expectedProduct2 = { 
     { 19, 23 }, 
     { 54, 65 }, 
     }; 
     test("Second test case", text2, expectedStrMatrices2, expectedMatrices2, expectedProduct2); 
    }// void main(String[] args) 

    private static void displayMatrix(int[][] matrix) { 
     for(int i = 0; i < matrix.length; ++i) { 
     for(int j = 0; j < matrix[i].length; ++j) { 
      System.out.printf("%2d ", matrix[i][j]); 
     } 
     System.out.println(); 
     } 

    } 

    static boolean compare(String[][] left, String[][] right) { 
     if(left.length != right.length) { 
     return false; 
     } 
     for(int i = 0; i < left.length; ++i) { 
     if(left[i].length != right[i].length) { 
      return false; 
     } 
     for(int j = 0; j < left[i].length; ++j) { 
      if(! left[i][j].equals(right[i][j])) { 
       return false; 
      } 
     } 
     } 
     return true; 
    } 

    static boolean compare(int[][][] left, int[][][] right) { 
     if(left.length != right.length) { 
     return false; 
     } 
     for(int i = 0; i < left.length; ++i) { 
     if(left[i].length != right[i].length) { 
      return false; 
     } 
     for(int j = 0; j < left[i].length; ++j) { 
      if(left[i][j].length != right[i][j].length) { 
       return false; 
      } 
      for(int k = 0; k < left[i][j].length; ++k) { 
       if(left[i][j][k] != right[i][j][k]) { 
        return false; 
       } 
      } 
     } 
     } 
     return true; 
    } 

    private static boolean compare(int[][] left, int[][] right) 
    { 
     if(left.length != right.length) { 
     return false; 
     } 
     for(int i = 0; i < left.length; ++i) { 
     if(left[i].length != right[i].length) { 
      return false; 
     } 
     for(int j = 0; j < left[i].length; ++j) { 
      if(left[i][j] != right[i][j]) { 
       return false; 
      } 
     } 
     } 
     return true; 
    } 
} 
+0

感謝您的努力,這有助於我的閱讀階段工作。 –

相關問題