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

Java 从一个文本文件中读取两个矩阵,java,file,matrix,filereader,Java,File,Matrix,Filereader,这是一个长的 我有一个很奇怪的问题。我需要从文本文件中读取两个矩阵,将它们相乘,然后打印出结果。这很容易。问题在于,包含矩阵的文件如下所示: 1 2 1 2 3 3 4 4 5 6 5 6 7 8 1 2 1 2 3 3 4 4 5 6 7 8 这个疯狂的东西是如何工作的(仅供参考,您可以跳过这部分): 读下第一列。一旦你点击了空格或者文件的结尾,你就有了第一个矩阵中的行数 逐行计算每行的整数数。一旦该计数下降,您就知道第二个矩阵有多少行了。如果第一个矩阵比文件“短”,那么这个步

这是一个长的

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

1 2 1 2 3
3 4 4 5 6
5 6
7 8
1 2 1 2 3
3 4 4 5 6
      7 8
这个疯狂的东西是如何工作的(仅供参考,您可以跳过这部分):

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

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

  • 由于乘法要求矩阵1的列数与矩阵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
    5 6
    7 8
    
    1 2 1 2 3
    3 4 4 5 6
          7 8
    
    所以我只需要根据左下角是整型还是空白进行一些条件处理。我正在考虑将整个文件读入一个2D数组,然后从那里进行操作

    下面是我的正式问题:

    我需要单独读取文件的每个字符,无论是int还是空格,这样我就可以构建一个忠实的数组[]。最好的方法是什么?我尝试过Scanner、StringTokenizer、FileInputStream、BufferedInputStream、Reader和FileReader,但它们都没有给我一个简单的字符一个字符


    其次,关于将矩阵从统一数组[]拆分为两个更小的数组[][]的任何建议?

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


    请注意,
    read()
    方法在EOF处返回-1。否则,将返回值强制转换为字符。

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

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

    • 我无法想象在一次运行中读取一个数组数组是可能的,因为在读取文件时,您事先不知道行数。因此,您需要使用集合类
    • 我建议使用LinkedList,因为删除wit pop比使用由数组支持的集合效率更高、速度更快
    • LinkedList还可以在传递列表时有效地对矩阵进行乘法

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

    当你在文件中搜索这两位信息时, 如果两个字符都没有跳过,也要查找第一个或最后一个字符是否为空格 如果第一个阵列被扫描,直到你撞到第二个阵列 如果最后一个是,向后扫描,直到碰到第一个 当然,另一种可能性是两个尺寸相同的数组

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


    这有点残酷,但它会工作并且很容易测试。

    我建议将问题分为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;
       }
    }
    
    import java.util.ArrayList;
    导入java.util.List;
    公共类矩阵{
    静态字符串[][]文本2StrMatrix(字符串[]文本){
    Listw=newarraylist(12);
    用于(字符串行:文本)
    {
    Listl=newarraylist(line.length()/2);
    对于(int i=0;i0){
    ++计数;
    }
    }
    返回计数;
    }
    静态int[][]strMatrices2IntegerMatrices(字符串[][]str){
    int count=str[0]。长度;
    int行=0;
    while(行0){
    第一个=i;
    }
    }
    int列=0;
    如果(第一个>0){
    列=第一列;
    }
    否则{
    列=countValues(str[行]);
    }
    列表w=新数组