0

これは長いものです。

私は非常に奇妙な問題を抱えています。テキストファイルから2つの行列を読み取り、それらを乗算してから、結果を出力する必要があります。それはすべてとても簡単です。問題は、行列を含むファイルが次のようになることです。

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

このクレイジーな動作は次のとおりです(参考までに、この部分はスキップできます)。

  1. 最初の列を読みます。空白またはファイルの終わりを押すと、最初のマトリックスの行数がわかります。

  2. 行ごとに、行ごとの整数の数を数えます。その数が減ると、2番目の行列の行数がわかります。最初のマトリックスがファイルよりも「短い」場合、2番目のマトリックスは単にファイル内の行数になるため、この手順は不要です。

  3. 乗算では、行列1の列数が行列2の行数と同じである必要があるため([3x6 * 6x4]は有効ですが、[3x6 * 5x4]は無効です)、行列1の列数を知ることにより、行数を見つけることができます。マトリックス2で、またはその逆。

どちらかの値を見つける必要があります。

したがって、そのファイルマトリックスから1つは

1 2
3 4
5 6
7 8

そして2つは

1 2 3
4 5 6

したがって、1列目の行と最後の行の列数を数えてすべてを見つけることができると思うかもしれませんが、ファイルは次のようになる場合があります。

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

したがって、左下隅がintであるか空白であるかに応じて、条件付きのジャグリングが必要です。ファイル全体を2D配列に読み込んで、そこから操作することを考えています。

だからここに私の正式な質問があります:

忠実な配列[][]を作成できるように、ファイルのすべての文字を個別に読み取る必要があります。これは、intであろうと空白であろうと関係ありません。それを行うための最良の方法は何ですか?Scanner、StringTokenizer、FileInputStream、BufferedInputStream、Reader、およびFileReaderを試しましたが、いずれも単純な文字ごとの文字を表示しません。

次に、統合されたArray[][]からの行列を2つの小さなArray[][]に分割するための提案はありますか?

4

4 に答える 4

0

テキストファイルは1行ずつしか読み取ることができません。したがって、行を読み取り、String.split( "")を使用して分割し、結果のデータをIntegerのリンクリストを保持するリンクリストに入力します。分割されたデータの位置を追跡する必要があることに注意してください。 2番目のケースでは、2番目のマトリックスの開始位置を記憶するために入力文字列にあります。

LinkedList<LinkedList<Integer>>

ファイルのすべての行を読み取った後、「最高の」マトリックスの完全な行数が得られ、リンクリスト(Lisp)から同じ時点で同じデータを削除しながら、最初のマトリックスのデータを配列に入れることができます。 。ポップ())。

  • ファイルの読み取り中に行数が事前にわからないため、1回の実行で配列の配列を読み取ることができるとは想像できません。したがって、コレクションクラスを使用する必要があります。
  • 配列に基づくコレクションを使用するよりも、ウィットポップを削除する方が非常に効率的で高速であるため、LinkedListを使用することをお勧めします。
  • LinkedListは、リストを通過するときにマトリックスを効率的に乗算するためにも機能します。
于 2012-11-14T22:15:05.167 に答える
0

FileInputStreamを使用して、ファイルを1文字ずつ読み取ることができるはずです。

read()このメソッドはEOFで-1を返すことに注意してください。それ以外の場合は、戻り値をcharにキャストします。

于 2012-11-14T22:07:30.377 に答える
0

どちらの行列でも、最大行数は行数であり、最大列数は行の長さ+ 1/2であり、行末に使用されるもの(CRLFなど)を除きます。

ファイルをスキャンしてこれらの2ビットの情報を探します。また、最初の文字がスペースである場合は最初または最後の文字がスペースであるかどうかを確認します。他の可能性はもちろん同じ寸法の2つのアレイです。

これらの情報を利用して、2つの配列を作成し、ファイルを再度スキャンして、値を適切な場所にスロットすることができます。

少し残酷ですが、機能し、テストも簡単です。

于 2012-11-14T22:20:45.770 に答える
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;
   }
}
于 2012-11-14T22:24:40.997 に答える