2012-11-14 112 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

感谢您的努力,这有助于我的阅读阶段工作。 –

相关问题