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

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

ただいまの
回答率

90.33%

  • Java

    14412questions

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

多次元配列の値の比較

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,128

TomofumiKimura

score 16

このクラスの 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

自分が書いたこのメッソッドの場合2番目のfor ループにあるt.length がいつも4になっています。多分それが原因でうまく行ってないんだと思うのですが、どうなんでしょうか?
どうしたらうまく比べられるのでしょうか?

package week04;

/**
 * Skeleton code for an array based implementation of Young's tableau.
 *
 * @author Iain Hewson
 */
public class TableauApp {

    /**
     * The main method is just used for testing.
     *
     * @param args command line arguments are not used.
     */
    public static void main(String[] args) {
        final int [] [] valid = {{1,4,5,10,11},{2,6,8},{3,9,12},{7}};
    System.out.println(columnValuesIncrease(valid));

    }

    /**
     * Determines whether the array passed to it is a valid tableau or not.
     *
     * @param t a two-dimensional array to test for tableau-ness.
     *
     * @return true if the parameter is a valid tableau, otherwise false
     */
    public static boolean isTableau(int[][] t){
        return false;
    }
    /**
     * Returns true if no row is longer than a preceding row,
     * Otherwise false.
     * @param t a two-dimensional array which represents a tableau.
     * @return true if no row is longer than a preceding row,
     * otherwise false.
     */
    public static boolean rowLengthsDecrease(int [] [] t){
    boolean result = true;
    // check if the row is not empty
    if (t[0].length != 0){
        System.out.println("The two dimentional array is this");
        System.out.println(toString(t));
        int first = t[0].length;// the first arrays element.
        int second = 0;// second longest or equal to the first element.
        for (int i =1; i<t.length;i++){
            // t.length = 4
        second  = t[i].length;// 0 changed to 4
        if(result){// if the result is still true
            if(first >= second ){// if first is longer or same as second
            first = second;// change first value to second value(second row length)
            result = true;
            }else{
            System.out.println("No row is longer than a preceding row");
            result = false;
            }
        }// second if  
        }// for 
    }else{
        result = false;
    }// first if 
    return result;
    }// method 
    /**
     *returns true if no row is longer than a preceding row, otherwise false.
     *@param t two dimentional array
     *@return true if the integers are increasing from left to right.
     */
    public static boolean rowValuesIncrease(int [] [] t){

    boolean result = true;
    for (int i =0; i<t.length; i++){
        int first = t[i][0];// first elements for each array
        int second =0;
        for (int j = 1; j<t[i].length;j++){


        if (t[i][j] > first){
            second = t[i][j];
            System.out.println("second int is "+" " + second);
            System.out.println("First  int is "+" " + first);
            System.out.println("");
            result = true;
            first = second;
            System.out.println("Current result " + "" + result);
        }else{
            result = false;
            return false;
        }// if end

        }// end for loop 
    }// end for loop
    return result;


    }// end method

    /**
     * Returns true if from top to bottom in any column,
     * the integers are increasing otherwise false.
     * @param t two dimentional array 
     * @return true if the integers are increasing
     * from top to bottom in any column.
     */
    public static boolean columnValuesIncrease(int [][] t){
    // first integer in the two dimentional array
        boolean result = true;
    for (int j =0; j<t[j].length; j++;){
    for (int i = 1; i<t.length; i++){
      if (t[i][j] < first){
         result = false;
         return result;
      }else{
        first = t[i][j];
      }
    }
    }
       return result;




    }

public static boolean isSetOf1toN (int [] [] t){
    boolean result = true;
    // count the number of cells in the array
    int count = 0;// 10
    // get total number of cells 
    for (int i = 0; i<t.length; i++){
        count += t[i].length;

    }
    // get the last number in the array

    int n = t.length-2;//2
    int f = t[n][t[n].length-1];
    System.out.println(n);
    if (f  != count ){
        result = false;

    }

    return result;


    }
    /**
     *  Returns a string representation of an array based tableau.
     *
     * @param t a two-dimensional array which represents a tableau.
     *
     * @return a string representation of an array based tableau.
     */
    public static String toString(int[][] t) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < t.length; i++) {
            for (int j = 0; j < t[i].length; j++) {
                result.append(String.format("%-4s", t[i][j]));
            }
            if (i < t.length-1) {
                result.append("\n");
            }
        }
        return result.toString();
    }

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • akabee

    2017/03/24 09:36

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

    キャンセル

  • swordone

    2017/03/26 12:38

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

    キャンセル

  • TomofumiKimura

    2017/03/26 12:42

    そうですね。そうします。

    キャンセル

回答 5

+1

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

【やりたいこと】
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とする。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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文

for (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]はないため、この回避をしないと例外発生
public static boolean columnValuesIncrease(int [][] t){
    int max = 0;
    for (int[] a : t) {
        max = Math.max(max, a.length);
    }
    for (int j = 0; j < max; j++) {
        int lastNum = Integer.MIN_VALUE;
        for (int i = 0; i < t.length; t++)
            if (t[i].length <= j) continue;
            if (t[i][j] < lastNum) {
                return false;
            }
            lastNum = t[i][j];
        }
    }
    return true;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/24 11:04 編集

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

    キャンセル

  • 2017/03/26 10:47

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

    キャンセル

  • 2017/03/26 11:08

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

    キャンセル

  • 2017/03/26 11:12

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

    キャンセル

  • 2017/03/27 10:58

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

    キャンセル

checkベストアンサー

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)のものです。他のみなさんはより前提条件をより緩和した回答を載せておられるので区別してください。

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/25 17:00

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

    キャンセル

  • 2017/03/25 17:27 編集

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

    キャンセル

  • 2017/03/25 17:42

    ありがとうございます!!!

    キャンセル

  • 2017/03/25 18:13

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

    キャンセル

  • 2017/03/25 18:18

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

    キャンセル

  • 2017/03/26 11:25 編集

    iの終了条件が足りませんね。
    この条件だとj=0の時に「各行の長さ0より大きい」に反する行がないためiが4まで行って、
    t[4]を参照しようとして例外になります。
    なんでArrayIndexOutOfBoundsExceptionが"3"で出るのかはわかりませんが…

    とりあえず内側ループの継続条件は
    i < t.length && j < t[i].length
    が正しいかと。

    キャンセル

  • 2017/03/26 11:55 編集

    すみません。しょうもないバグがありましたね。根本的に「何行まであるか」のチェックが抜けてました。失礼しました。

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

    間違いを訂正いただき恐縮です。>swordoneさん

    キャンセル

  • 2017/03/26 12:24

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

    キャンセル

0

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

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

追記

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

class AZ0{
public static void main(String[] args){

final int [] [] t = {{1,4,5,10,11},{2,6,8},{3,9,12},{7}};

System.out.println(columnValuesIncrease(t));

}

public static boolean columnValuesIncrease(int[][] t){

int firstep=0;
int tem=0;
for(int i=0;i<t[0].length;i++){

for(int n=0;n<t.length;n++){

if(n==0){
firstep=t[n][i];
continue;
}

try{
tem=t[n][i];
}catch(Exception e){
continue;
}


if(firstep>tem){
return false;
}
firstep=tem;

}

}

return true;

}

}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/26 10:56 編集

    ありがとうございます。

    キャンセル

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

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

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

  • Java

    14412questions

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