質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。

解決済

[Java]指定された行、列サイズと入力された行列のサイズが異なる場合、エラー文を出力したい

karintage
karintage

総合スコア5

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。

2回答

0評価

0クリップ

224閲覧

投稿2022/07/05 06:38

編集2022/07/11 23:50

前提

行列の値が保存されているテキストファイルを読み込み(テキストファイルは入力ストリームで指定、3つのファイルがある)、その内容を二次元配列に格納するプログラムを作成しています。

テキストファイルは

3 3
0.1 0.2 0.3
0.4 0.5 0.6
0.7 0.8 0.9

のように、1行目に行、列のサイズ、2行目以降が行列の内容となっています。
//追記
プログラム実行時に、以下のようにファイルを指定します。

javau Matrix A.txt B.txt C.txt

実現したいこと

以下の例のように、33行列と指定されているのに対し、実際の行列が23であるように、指定されたサイズと入力されたサイズが異なる場合、その旨("M×Nと行列のサイズが一致しません")を出力したいです。

3 3
1 2 3
1 2 3

発生している問題・エラーメッセージ

3 3
1 2 3
1 2 3
を入力した場合は

java.lang.NullPointerException at Matrix.read(Matrix.java:49) at Matrix.main(Matrix.java:154)

3 3
1 2
1 2
1 2
を入力した場合は

java.lang.ArrayIndexOutOfBoundsException: 2 at Matrix.read(Matrix.java:51) at Matrix.main(Matrix.java:154)

と出力されます。

該当のソースコード

Java

/** プログラム:ファイルの値を読み込み二次元配列に格納する 二次元配列を用いて行列積、和、差を計算する */ import java.io.*; import java.text.Format;/* フォーマットのため */ import java.text.DateFormat;/* 日付のフォーマット用 */ import java.util.Calendar; import java.text.SimpleDateFormat; public class Matrix{ private double[][] m;//条件(1)行列をprivate名,double型のメンバ変数とする private int row, col;//行サイズと列サイズをprivateなint型のメンバー変数とする /*条件(2)Matrixクラスのコンストラクタとして、無引数のものpublic Matrix()を作成 */ public Matrix(){ } /*条件(2)Matrixクラスのコンストラクタとして、(1)で述べた行と列を引数で与える2引数のものを作成*/ public Matrix(int M, int N){ this.row=M; this.col=N; m=new double[M][N]; } /*条件(6):M行N列の実数データ(スペース区切り)を記述したデータ用ファイルから読み込み、Matrixクラスのオブジェクトを生成する関数。*/ public Matrix read(String filename){ Matrix mat=new Matrix();//ダミーオブジェクトを作成 try { BufferedReader br = new BufferedReader(new FileReader(filename)); String[] rowcol = br.readLine().split(" ");//1行目読み込み(行と列のサイズが記述されている) mat.row = Integer.parseInt(rowcol[0]);//行のサイズ mat.col = Integer.parseInt(rowcol[1]);//列のサイズ mat.m = new double[mat.row][mat.col];//配列のサイズを指定 for (int row_read = 0; row_read < mat.row; row_read++) {//読み込む行を指定 if(rowcol==null){ System.err.println("M×Nと行列のサイズが一致しません"); System.exit(1); } String[] record = br.readLine().split(" "); //(row_read)行の文字列を読み込み、空白で分割 for (int col_read = 0; col_read < mat.col; col_read++){//読み込む列を指定 if(record[col_read]==null){ System.err.println("M×Nと行列のサイズが一致しません"); System.exit(1); } mat.m[row_read][col_read] = Double.parseDouble(record[col_read]);//読み込んだ値をdouble型に変換して二次元配列に格納 } } br.close(); } /*ファイルが存在しない場合、エラーを出力しプログラム終了 */ catch (FileNotFoundException e) { e.printStackTrace(); System.exit(1); } /*フォーマットエラーの場合、エラーを出力しプログラム終了 */ catch (NumberFormatException e) { e.printStackTrace(); System.exit(1); } /*stackした場合、エラーを出力しプログラム終了 */ catch (IOException e) { e.printStackTrace(); System.exit(1); } return mat;//作成したオブジェクトを返り値とする } /*条件:(5)Matrixクラスが保持するM×N行列の中身の要素をプリントするvoid型のprint()関数*/ public void print(){ System.out.printf("サイズ:(%d,%d)\n",row,col);//行列のサイズを出力 /*2重ループで行、列を指定して行列の中身を出力 */ for (int i = 0; i < row; i++) { System.out.print("|"); for (int j = 0; j < col; j++){ System.out.print(" " + (String.format("%.6f",m[i][j])));//小数点7桁目を四捨五入して出力 } System.out.println("|"); } System.out.println();//改行 } /*条件(3) :行列の乗算を実行し、結果を別のMatrixクラスのオブジェクトとして返す関数*/ public Matrix multiply(Matrix B) { /*行列A:M×K,行列B:K×NのKが一致していない場合エラー文を出力し、プログラムを終了*/ if (col != B.row){ System.err.print("Aの列サイズとBの行サイズが一致しません"); System.exit(1); } Matrix D = new Matrix(row, B.col);//乗算の結果を格納するオブジェクトDを作成 /*3重ループで行列積を計算 */ for (int i = 0; i < row; i++){ for (int j = 0; j < B.col; j++) { for (int k = 0; k < B.row; k++){ D.m[i][j] += m[i][k] * B.m[k][j]; } } } return D;//オブジェクトDを戻り値とする } /*条件(4):Matrixクラスの2つのサイズが一致するオブジェクトに対して、要素ごとの加算(add)を行う関数*/ public Matrix add(Matrix B){ /*条件(D):Matrixクラスの2つのサイズが一致しない場合プログラムを終了*/ if(row != B.row || col != B.col){ System.err.print("行列Cと行列Dの行、列のサイズが異なります"); System.exit(1); } Matrix E = new Matrix(row,col);//加算の結果を格納するオブジェクトEを作成 /*2重ループで加算を行う */ for(int i=0; i<row; i++){ for(int j=0; j<col; j++){ E.m[i][j]=m[i][j]+B.m[i][j]; } } return E;//オブジェクトEを戻り値とする } /*条件(4):Matrixクラスの2つのサイズが一致するオブジェクトに対して、要素ごとの減算(subtraction)を行う関数*/ public Matrix sub(Matrix B){ /*条件(D):Matrixクラスの2つのサイズが一致しない場合プログラムを終了*/ if(row != B.row || col != B.col){ System.exit(1); } Matrix F = new Matrix(row,col);//減算の結果を格納するオブジェクトFを作成 /*2重ループで加算を行う */ for(int i=0; i<row; i++){ for(int j=0; j<col; j++){ F.m[i][j]=m[i][j]-B.m[i][j]; } } return F;//オブジェクトFを戻り値とする } /*main文 */ public static void main(String[] args){ try { Matrix mat=new Matrix();//条件(A):main関数から無引数のMatrixのコンストラクタを呼び出し、Matrixオブジェクトを生成する /*条件(B):コマンドラインからの引数(args[])を与え、個々のファイルを読み込み、行列の中身をプリントする 引数が3でないときは警告文を出力し、プログラム終了*/ if(args.length != 3){ System.err.println("「行列データファイルは3つ与えてください」"); System.exit(1); } Matrix A=mat.read(args[0]);//args[0]から作成した配列を配列Aとする System.out.print("入力行列A,"); A.print();//配列Aを出力 Matrix B=mat.read(args[1]);//args[1]から作成した配列を配列Bとする System.out.print("入力行列B,"); B.print();//配列Bを出力 Matrix C=mat.read(args[2]);//args[2]から作成した配列を配列Cとする System.out.print("入力行列C,"); C.print();//配列Cを出力 /*条件(C):3=<M,N,K=<10を満たしていない場合は警告文を出力、プログラム終了*/ if(A.row<3||A.row>10||A.col<3||A.col>10||B.col<3||B.col>10){ System.err.println("3=<M,N,K=<10を満たしていません"); System.exit(1); } /*条件(C):M,N,Kがすべて同じ場合、警告文を出力、プログラム終了 */ if(A.row==A.col&&A.col==B.col&&A.row==B.row){ System.err.println("M,N,Kのどれか一つは他と違う値にしてください"); System.exit(1); } /*条件(C):乗算を実行する */ Matrix D=A.multiply(B); System.out.print("出力 積行列 D=A×B,"); D.print(); /*条件(D):行列Cと行列Dの要素ごとの加算、結果を出力*/ Matrix E=C.add(D); System.out.print("出力 要素和行列 E=C+(A×B),"); E.print(); /*条件(D):行列Cと行列Dの要素ごとの減算、結果を出力*/ Matrix F=C.sub(D); System.out.print("出力 要素差行列 F=C-(A×B),"); F.print(); } catch (Exception e) { e.printStackTrace(); } } }

試したこと

Matrix read 内で行を読み込むたびに、nullではないか確認し、行数の不一致を検知(指定されたサイズと一致していれば、nullになる前にfor文が終了しているはずと考えました)
列数の不一致に関してはわかりませんでした。

補足情報(FW/ツールのバージョンなど)

Java バージョン8

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

jimbe

2022/07/05 06:46

> テキストファイルは入力ストリームで指定 これはドコのことを言っているのでしょうか。 プログラムのパラメータとしてファイル名を 3 つ指定されているようですが。 また、コードが尻切れになっているようです。 全体をコピペして動作するよう、最後の } まで含むようにされたほうが良いように思います。 そして、このご質問は何方かの課題の回答を求めておられるように見えますが、他人に聞いて良い類でしょうか。
jimbe

2022/07/05 06:54 編集

行列指定とデータ数で、データ数が少ない場合を主にお考えのようですが、データ数が多い場合はどうされるつもりでしょうか。 >Matrix read 内で行を読み込むたびに、nullではないか確認し、行数の不一致を検知(指定されたサイズと一致していれば、nullになる前にfor文が終了しているはずと考えました) そのような部分が見当たりませんが、実際やってみてどうだったのでしょうか。もしダメだったのでしたら、なぜダメだったのかはどうお考えになりましたか。
karintage

2022/07/05 07:49

データ数が多い場合に関しては今回は考えていません。 >そのような部分が見当たりませんが、実際やってみてどうだったのでしょうか。もしダメだったのでしたら、なぜダメだったのかはどうお考えになりましたか。 if(rowcol==null){ System.err.println("M×Nと行列のサイズが一致しません"); System.exit(1); } の処理で行数の不一致を検知しているつもりです。 実行されない原因としては、ファイルの最後の行を読み込んだ後、br.ReadLine()==nullとなっているものの、rowcol==nullではないためと考えます。 しかし、 if(br.ReadLine()==null) とするとエラー(NullPointerException)となります。こちらの原因については理解できていません。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

コンストラクタ

オブジェクト指向言語において、オブジェクトを生成時に呼び出され、データの初期化などを行なう関数・メソッドのことである。