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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

Q&A

解決済

5回答

6784閲覧

多次元配列の値の比較

TomofumiKimura

総合スコア65

Java

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

0グッド

0クリップ

投稿2017/03/24 00:06

編集2017/03/26 03:42

このクラスの public static boolean columnValuesIncrease(int [][] t)で困っています。まずこのメソッドの役割は2次元配列の値を縦の方向で比較します。何を比較するのかというと、上から下に向かっていく列の値は大きいかどうかを確認しなければいけません。メインにあるvalid から例えると、1< 2 < 3 < 7 なのであっています。そして次の縦の列。4< 6 < 9 なのでtrue です。こんな具合に比較していくメッソッドです。上から縦の方向で値を比較するのは書けたのですが、
1, 4, 5, 10 11
2, 6, 8
3, 9, 12
7
自分が書いたこのメッソッドの場合2番目のfor ループにあるt.length がいつも4になっています。多分それが原因でうまく行ってないんだと思うのですが、どうなんでしょうか?
どうしたらうまく比べられるのでしょうか?

Java

1package week04; 2 3/** 4 * Skeleton code for an array based implementation of Young's tableau. 5 * 6 * @author Iain Hewson 7 */ 8public class TableauApp { 9 10 /** 11 * The main method is just used for testing. 12 * 13 * @param args command line arguments are not used. 14 */ 15 public static void main(String[] args) { 16 final int [] [] valid = {{1,4,5,10,11},{2,6,8},{3,9,12},{7}}; 17 System.out.println(columnValuesIncrease(valid)); 18 19 } 20 21 /** 22 * Determines whether the array passed to it is a valid tableau or not. 23 * 24 * @param t a two-dimensional array to test for tableau-ness. 25 * 26 * @return true if the parameter is a valid tableau, otherwise false 27 */ 28 public static boolean isTableau(int[][] t){ 29 return false; 30 } 31 /** 32 * Returns true if no row is longer than a preceding row, 33 * Otherwise false. 34 * @param t a two-dimensional array which represents a tableau. 35 * @return true if no row is longer than a preceding row, 36 * otherwise false. 37 */ 38 public static boolean rowLengthsDecrease(int [] [] t){ 39 boolean result = true; 40 // check if the row is not empty 41 if (t[0].length != 0){ 42 System.out.println("The two dimentional array is this"); 43 System.out.println(toString(t)); 44 int first = t[0].length;// the first arrays element. 45 int second = 0;// second longest or equal to the first element. 46 for (int i =1; i<t.length;i++){ 47 // t.length = 4 48 second = t[i].length;// 0 changed to 4 49 if(result){// if the result is still true 50 if(first >= second ){// if first is longer or same as second 51 first = second;// change first value to second value(second row length) 52 result = true; 53 }else{ 54 System.out.println("No row is longer than a preceding row"); 55 result = false; 56 } 57 }// second if 58 }// for 59 }else{ 60 result = false; 61 }// first if 62 return result; 63 }// method 64 /** 65 *returns true if no row is longer than a preceding row, otherwise false. 66 *@param t two dimentional array 67 *@return true if the integers are increasing from left to right. 68 */ 69 public static boolean rowValuesIncrease(int [] [] t){ 70 71 boolean result = true; 72 for (int i =0; i<t.length; i++){ 73 int first = t[i][0];// first elements for each array 74 int second =0; 75 for (int j = 1; j<t[i].length;j++){ 76 77 78 if (t[i][j] > first){ 79 second = t[i][j]; 80 System.out.println("second int is "+" " + second); 81 System.out.println("First int is "+" " + first); 82 System.out.println(""); 83 result = true; 84 first = second; 85 System.out.println("Current result " + "" + result); 86 }else{ 87 result = false; 88 return false; 89 }// if end 90 91 }// end for loop 92 }// end for loop 93 return result; 94 95 96 }// end method 97 98 /** 99 * Returns true if from top to bottom in any column, 100 * the integers are increasing otherwise false. 101 * @param t two dimentional array 102 * @return true if the integers are increasing 103 * from top to bottom in any column. 104 */ 105 public static boolean columnValuesIncrease(int [][] t){ 106 // first integer in the two dimentional array 107 boolean result = true; 108 for (int j =0; j<t[j].length; j++;){ 109 for (int i = 1; i<t.length; i++){ 110 if (t[i][j] < first){ 111 result = false; 112 return result; 113 }else{ 114 first = t[i][j]; 115 } 116 } 117 } 118 return result; 119 120 121 122 123 } 124 125public static boolean isSetOf1toN (int [] [] t){ 126 boolean result = true; 127 // count the number of cells in the array 128 int count = 0;// 10 129 // get total number of cells 130 for (int i = 0; i<t.length; i++){ 131 count += t[i].length; 132 133 } 134 // get the last number in the array 135 136 int n = t.length-2;//2 137 int f = t[n][t[n].length-1]; 138 System.out.println(n); 139 if (f != count ){ 140 result = false; 141 142 } 143 144 return result; 145 146 147 } 148 /** 149 * Returns a string representation of an array based tableau. 150 * 151 * @param t a two-dimensional array which represents a tableau. 152 * 153 * @return a string representation of an array based tableau. 154 */ 155 public static String toString(int[][] t) { 156 StringBuilder result = new StringBuilder(); 157 for (int i = 0; i < t.length; i++) { 158 for (int j = 0; j < t[i].length; j++) { 159 result.append(String.format("%-4s", t[i][j])); 160 } 161 if (i < t.length-1) { 162 result.append("\n"); 163 } 164 } 165 return result.toString(); 166 } 167 168} 169

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akabee

2017/03/24 00:36

どう上手くいっていないのか、記載いただけませんか?エラーになるのですか?結果が何か期待と異なるのですか?なおt.lengthは常に4になると思いますよ。多次元配列の一次元目の要素を4つ宣言されていますので。それが期待と異なりますか?
swordone

2017/03/26 03:38

新しい質問なら別に立てなさい。ここに混ぜたらわけがわからなくなる。こっちはこっちで疑問が解消したのか、まだ何か疑問があるのかはっきりさせてください。
guest

回答5

0

Javaでは多次元配列という考え方ではなく、「配列の配列」という考え方をします。
今回のこの配列は、

t[0]:{1,4,5,10,11} t[1]:{2,6,8} t[2]:{3,9,12} t[3]:{7}

という、int配列を4つもったint配列の配列です。
t.lengthはint配列の要素数ということになるため、必ず4になります。
ここで問題になるのは、最初のfor文

java

1for (int j =0; j<t[j].length; j++;)

おそらく横方向で見た番号での縦の長さ、つまりj=1の時は{4,6,9}という配列を見て長さをとろうとしているのでしょうが、そんなことにはなりません。jが3になった時の3 < t[3].length(=1)がfalseになりループを抜けてしまいます。

これをやろうとしたら、まず横方向の最大の長さをとる必要があります。t[0]が最長という保証があればいいのですが、そうでないとしたらまずこのためにforを回して最長長さを調べる必要があります。
そうしたら、まずt[i][j]のjを固定します。jの範囲は今調べた横方向最長まで、つまり0~(最長)-1です。
例えばj=1で考えますが、t[i][1]を、iを動かしながら増加しているか調べます。ただし、この時t[i]に1番の要素があるか、つまりt[i].lengthが2以上あるかを確かめる必要があります(しないと例外発生)。

↓j=1ならこの縦方向を見る(各配列の1番目の要素) t[0]:{1,4,5,10,11} <-t[0][1]は4 t[1]:{2,6,8} <-t[1][1]は6>4で成立 t[2]:{3,9,12} <-t[2][1]は9>6で成立 t[3]:{7} <-t[3][1]はないため、この回避をしないと例外発生

java

1public static boolean columnValuesIncrease(int [][] t){ 2 int max = 0; 3 for (int[] a : t) { 4 max = Math.max(max, a.length); 5 } 6 for (int j = 0; j < max; j++) { 7 int lastNum = Integer.MIN_VALUE; 8 for (int i = 0; i < t.length; t++) 9 if (t[i].length <= j) continue; 10 if (t[i][j] < lastNum) { 11 return false; 12 } 13 lastNum = t[i][j]; 14 } 15 } 16 return true; 17} 18

投稿2017/03/24 00:56

編集2017/03/26 02:16
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2017/03/26 02:12 編集

あ、lastNumの更新にミス… ※修正しました。
TomofumiKimura

2017/03/26 01:47

すみません。自分頭悪いんでもう少しわかりやすいように説明してもらえないでしょうか??すみません。
swordone

2017/03/26 02:08

わからないのは仕方ないにしても、もう少し聞き方があるのでは? この長い回答のどこをわかりやすく説明すればいいのか、 さもないとすべて説明しなおさなければならず、それはさすがに厚かましいのでは?
TomofumiKimura

2017/03/26 02:12

確かにそうですね。すみませんでした。
swordone

2017/03/27 01:58

で、結局どこか言わないんですね
guest

0

恐らく以下の通りですね。

【やりたいこと】
1.列番号を決める
2.各行について、1で決めた列番号に対応した値を上から順に比較する。もし該当の行に1で決めた列がなければ、比較対象にしない。
3.上から順に比較して下に向かえば向かうほど値が大きければtrueとする。そうでなければfalseとする。

【現状できていないこと】
2.のうち、「もし該当の行に1で決めた列がなければ」という条件が考慮できていないと思います。

【現状】
1.列番号を決める
2.全ての行に対して、1で決めた列番号の要素を参照する。
3.上から順に比較して下に向かえば向かうほど値が大きければtrueとする。そうでなければfalseとする。

→2.の処理で、多次元配列の4番目には列の2つ目がないのでエラーになるのではないでしょうか。

【改善案】
1.列番号を決める
2.全ての行に対して、1で決めた列番号の要素を抽出して別の配列に格納する。その際、1で決めた列番号が無ければ、エラーにならないようスキップする。
3.2で求めた別の配列について、上から順に比較して下に向かえば向かうほど値が大きければtrueとする。そうでなければfalseとする。

投稿2017/03/24 00:47

akabee

総合スコア1947

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

比べる方法として以下のようなものが考えられます

java

1class AZ0{ 2public static void main(String[] args){ 3 4final int [] [] t = {{1,4,5,10,11},{2,6,8},{3,9,12},{7}}; 5 6System.out.println(columnValuesIncrease(t)); 7 8} 9 10public static boolean columnValuesIncrease(int[][] t){ 11 12int firstep=0; 13int tem=0; 14for(int i=0;i<t[0].length;i++){ 15 16for(int n=0;n<t.length;n++){ 17 18if(n==0){ 19firstep=t[n][i]; 20continue; 21} 22 23try{ 24tem=t[n][i]; 25}catch(Exception e){ 26continue; 27} 28 29 30if(firstep>tem){ 31return false; 32} 33firstep=tem; 34 35} 36 37} 38 39return true; 40 41} 42 43}

投稿2017/03/24 01:15

編集2017/03/25 08:05
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomofumiKimura

2017/03/26 02:02 編集

ありがとうございます。
guest

0

ベストアンサー

t[N][M]という二次元配列の一次元目(行数)の大きさは4ですが、二次元目の大きさ(列数)は各行で違いますので、常に4回ループするという考え方に問題があるのはご自分で認識されているとおりです。

もし行の長さが(前提A)「r行の長さはr+1行の長さより常に大きい」という仮定を置くなら(rowLengthsDecreaseがtrueとなる行列という仮定)、一番外側のループは

for (int j = 0; j < t[0].length; j++){ <=(最初の回答で余計な';'がありました。訂正しました)

でなければならないでしょう。オリジナルのコードは何列ループするかの上限をt[j].lengthとしていますがそれはi行目の列数が「トータルの列数と同じである」という前提が成立しなければ正しいとは言えなくなり、それは即ち「全部の行の列数が同じでなければ正しい条件判定とはいえなくなる」のであまり意味のある判定にならないことがおわかりでしょうか?

さて最初に述べた(前提A)で内側のループの条件を考えるとするなら各行の長さがまちまちなので一定回数ループするという方針ではダメで、「着目している列jが今回のループ対象行に存在するか」を判定しなければなりません。そう考えると以下の判定文が見えてくるはずです。

for (int i = 1; j < t[i].length; i++) {


補足:内側のループの意図がこの回答のままではわかりにくかったようなのでコードのイメージも載せてみます。念のためこのコードは(前提A)のものです。他のみなさんはより前提条件をより緩和した回答を載せておられるので区別してください。

java

1for (int j = 0; j < t[0].length; j++) { 2 // 0行目が一番長いという仮定を置いたので1行目からループ 3 for (int i = 1; j < t[i].length; i++) { 4 if (t[i - 1][j] >= t[i][j]) // 直前の行と比較 5 return false; 6 } 7} 8return true; //全てのチェックをパスしたらtrueを返す

蛇足:本件には関係ないですが綴りミスdimentionalを見つけました・・・

投稿2017/03/24 00:48

編集2017/03/25 08:26
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomofumiKimura

2017/03/25 08:00

for (int i = 1; j < t[i].length; i++)  int i が3になったときに t[3].length には1が入るのでこれではエラーが出ると思うんですけど。
KSwordOfHaste

2017/03/25 08:28 編集

エラーにならないのですが、自分の回答意図がちょっとわかりにくかったですね。 どういう考えだったか回答にコードを追加しました。 他の方とは前提の違う回答なのでそこに注意ください。
TomofumiKimura

2017/03/25 09:13

やはりエラーが出ます。 ArrayIndexOutOfBoundsException: 3  at week04.TableauApp.columnValuesIncrease(TableauApp.java:115) で2番目のfor loop に間違いがあると思うのですが
TomofumiKimura

2017/03/25 09:18

多分 j < t[i].lengthここのパートがint i = 3になったときに t[3].length になりますよね??でももし3列しかない二次元配列の場合だとエラーになると思うのですが・・
swordone

2017/03/26 02:34 編集

iの終了条件が足りませんね。 この条件だとj=0の時に「各行の長さ0より大きい」に反する行がないためiが4まで行って、 t[4]を参照しようとして例外になります。 なんでArrayIndexOutOfBoundsExceptionが"3"で出るのかはわかりませんが… とりあえず内側ループの継続条件は i < t.length && j < t[i].length が正しいかと。
KSwordOfHaste

2017/03/26 02:56 編集

すみません。しょうもないバグがありましたね。根本的に「何行まであるか」のチェックが抜けてました。失礼しました。 > 3列しかない二次元配列の場合だとエラーになると思うのですが・・ おっしゃるとおりですね。間違えた自分がいうのは失礼ですが、こうした間違いを「なぜ間違いなのか」や「どうすべきなのか」を考えてデバッグするというのがプログラマーの常だと思いますのでどんどん間違えてどんどんデバッグしてみると少しずつ論理がわかってくると思います。(間違えたくせにえらそうなこといってスミマセン) 間違いを訂正いただき恐縮です。>swordoneさん
TomofumiKimura

2017/03/26 03:24

いえいえ、その通りだと本当に思います。
guest

0

データは 4 行あります。t.length はこの行数を表しますので、ずっと 4 です。

仮に前の行が必ず後より長いのだとすると、j が後ろの行の長さ以上になった時点で比較をやめてその列の結果を true とすればいいと思います。そうではなく、行の長さが不定であるなら、その空白をどう扱うかで方法は変わってくると思います。

追記

あと、j のループの終了条件がおかしいですよ。

投稿2017/03/24 00:44

編集2017/03/24 00:47
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問