从一个文本文件中读取两个矩阵

时间:2012-11-14 21:47:44

标签: java file matrix filereader

这是一个很长的问题。

我有一个非常奇怪的问题。我需要从文本文件中读取两个矩阵,将它们相乘,然后打印出结果。这一切都很容易。问题是包含矩阵的文件如下所示:

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

这个疯狂的事情如何运作如下(仅供参考,你可以跳过这部分):

  1. 读下第一列。一旦你点击空格或文件的结尾,你就有了FIRST矩阵中的行数。

  2. 逐行计算每行的整数数。一旦计数下降,您就知道第二个矩阵有多少行。如果第一个矩阵比文件“更短”,则此步骤是不必要的,因为第二个矩阵只是文件中的行数。

  3. 由于乘法要求矩阵1的列数与矩阵2的行数相同([3x6 * 6x4]有效,[3x6 * 5x4]不是),那么通过知道矩阵1中的列数我们可以在矩阵2中找到行数,反之亦然。

  4. 我需要找到任何一个值。

    所以从那个文件矩阵中可以看出

    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还是空格,所以我可以构建一个忠实的Array [] []。这样做的最佳方法是什么?我已经尝试过Scanner,StringTokenizer,FileInputStream,BufferedInputStream,Reader和FileReader,但它们都没有给我一个char的简单char。

    其次,有关将矩阵从统一的Array [] []拆分为两个较小的Array [] [] s的建议吗?

4 个答案:

答案 0 :(得分:0)

您应该能够使用FileInputStream逐个字符地读取文件。

请注意,read()方法在EOF返回-1。否则将返回的值转换为char。

答案 1 :(得分:0)

文本文件只能逐行读取。 因此,读取一行,使用String.split(“”)将其拆分,并将结果数据填入链接列表,该列表包含Integer的链接列表。请记住,您必须跟踪拆分数据的位置在第二种情况下,在输入字符串中记住第二个矩阵的起始位置。

LinkedList<LinkedList<Integer>>

读取文件的所有行后您拥有“最高”矩阵的完整行数您可以将第一个矩阵的数据放入数组中,同时从链接的同一时间点删除相同的数据list(Lisp.pop())。

  • 我无法想象在一次运行中可以读入数组数组,因为在读取文件时你不知道行数。因此,您需要使用集合类。
  • 我建议使用LinkedList,因为删除wit pop非常有效,而且比使用由数组支持的集合更快。
  • LinkedList也可以在通过列表时有效地增加矩阵。

答案 2 :(得分:0)

对于两个矩阵,似乎最大行数是行数,最大列数是行的长度+ 1/2,不包括用于行尾的任何行(例如CRLF)

当您浏览文件中的那两位信息时, 如果两个char都没有跳过,也要查找第一个或最后一个char 如果第一个是扫描,直到你碰到第二个数组 如果是最后一个,则向后扫描直到碰到第一个 其他可能性当然是两个具有相同尺寸的阵列。

使用这些信息,您可以创建两个数组,然后再次扫描文件并将值插入适当的位置。

它有点残酷,但它会起作用并且易于测试。

答案 3 :(得分:0)

我建议将这个问题分为4个阶段:读取文本,构建一个String单元数组,构建一个整数矩阵数组,做矩阵的乘积:

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