<<3.配列 の目次
配列と繰り返し

問題7(難易度:3)                         2004年11月27日

次のメソッドについての設問に答えよ。 

      1:   public void methodA(int n) {
      2:          int[] ar = new int[n];
      3:          ar[0] = 1;
      4:          ar[1] = 1;
      5:          for(int i = 1; i < n - 1; i++) {
      6:                  for(int j = i; j > 0; j--) {
      7:                      ar[j] = ar[j - 1] + ar[j];
      8:                  }
      9:                  ar[i + 1] = 1;
    10:          }
    11:          for(int i = 0; i < n; i++) {
    12:                  System.out.print(ar[i] + " ");
    13:          }
    14:    }
        

設問1 仮引数nに−1が渡されたときの実行結果を下から選べ。

設問2 仮引数nに0が渡されたときの実行結果を下から選べ。

設問3 仮引数nに1が渡されたときの実行結果を下から選べ。
 
設問4 仮引数nに5が渡されたときの実行結果を下から選べ。
 
  A. 例外が発生する。
  B. 1 と出力される。
  C. 1 1 と出力される。
  D. 1 1 1 1 1 と出力される。
  E. 1 4 6 4 1 と出力される
  F. 何も出力されない。
解説
 まず局所変数arを見てください。int型の配列で、長さは仮引数nとして生成しています。配列の長さは実行時まで使われないので、このように変数で指定することができます。
 
 nが−1だとすると、配列生成時に長さがマイナスなので、NegativeArraySizeExceptionの例外が発生します。
 
 nが0や1だと、配列生成時には例外は発生しませんが、3行目、4行目でArrayIndexOutOfBoundsExceptionの例外が発生します。

 さてnが5の場合を考えましょう。for文による繰り返しですが二重になっていて、そこで配列に値を代入しています。いきなり全体を考えると混乱するので、まずは変数iとjの変化を調べましょう。nが5ですから、iは1から3まで1、2、3と変化します。jはiから1まで1ずつ減っていくので、i、i−1、i−2、...、2、1と変化します。iとjの関係を図にしてみましょう。iが増えるたびに、内側の繰り返し回数も増えていきます。

 次は配列arにどんな値が入るのか調べましょう。図に配列の中身の変化を示しました。


 図の1段目ではar[0]とar[1]に1が入ります。
 次の外側の繰り返しではiの値は1になります。図の2段目です。内側の繰り返しはjが1で1回だけ行われます。「ar[1]=ar[0]+ar[1];」なので、2が水色のar[1]に入ります。赤い線で示したように加算されることになります。
 次の外側の繰り返しはiが2になります。図の3段目です。内側の繰り返し1回目、jは2なので「ar[2]=ar[1]+ar[2];」となり、右の水色の3が求められます。2回目はjが1になり、左の3が求められます。
 最後の外側の繰り返しはiが3になります。図の4段目です。内側の繰り返し1回目は、jが3なので、「ar[3]=ar[2]+ar[3];」が実行され、右の4が求められます。内側の繰り返し2回目は、jが2なので、「ar[2]=ar[1]+ar[2];」が実行され、真ん中の6が入ります。同様に3回目で左の4が求められます。
 これが最終結果なので、1 4 6 4 1と出力されます。(見覚えありませんか?懐かしくありませんか?二項係数ですね。二項係数自体は知っていなくても、認定試験では何ら問題ありません。)

 内側の繰り返しで、jの値がiから1まで減っていきます。これを1からiまで増やしていくようにするとうまくいきません。時間があればなぜだか考えて見ましょう。
(このメソッドはstaticにしたいところですが、「読み物Java」の方でまだやってないので心苦しく思いstatic指定をしていません。)

解答 設問1 A    設問2 A    設問3 A    設問4 E

参考 読み物Java 第7章 一軒家よりアパート?  
     合格Java 2.演算子と制御文 問題6(for文による二重の繰り返しについて) 
問題8(難易度:2)                              2004年11月29日
次をコンパイル、実行したときの出力結果はどうなりますか。下から選びなさい。

         1:   int[] ar = { 10000, 5000, 2000, 1000, 500, 100, 50, 10, 5, 1 };
         2:   int x = 123456;
         3:   for(int i = 0; i < ar.length; i++) {
         4:           System.out.print(x / ar[i] + " ");
         5:           x %= ar[i];
         6:   }
  A. 1 2 3 4 5 6
  B. 12 24 61 123 246 1234 2469 12345 24691 123456
  C. 12 0 1 1 0 4 1 0 1 1
  D. 3456 3456 1456 456 456 56 6 6 1 0
解説
 演算子/と%の意味がわかっていれば、余り難しくはないでしょう。
 繰り返しの最初のいくつかを実際やってみれば、選択肢の中から選ぶのは簡単です。まずiが0のとき、ar[i]は10000なので、図にあるように12が出力されます。int同士の除算は、小数点以下切捨てでしたね。
   x %= ar[i];

  x = x % ar[i];
ですから、余りの3456が新しいxの値になります。
 iが1のときは、同じことを10000の代わりに5000でやればいいので、0が出力され、新しいxは3456のままです。ここでもう正解はCであることがわかりました。本試験ではこれ以上モタモタせずに次の問題へ行きましょう。参考に図には最後までの経過を示しました。お分かりですか、123456円を金種別に必要枚数を計算していたのです。(2000円札はまだあるんですよねぇ)


解答 C

参考 読み物Java 第7章 一軒家よりアパート?
問題9(難易度:3)                                     2004年11月30日
次をコンパイル、実行した結果、「7」と出力された。XXXの部分に入る演算子はどれか、下から選びなさい。

   1: public class Main {
      2:     public static void main(String[] args) {
      3:            int[] a = { 1, 5, 7, 2, 4, 7 };
      4:            int x = a[0];
      5:            for (int i = 1; i < a.length; i++) {
      6:                    if (x  XXX a[i]) {
      7:                            x = a[i];
      8:                    }
      9:            }
    10:             System.out.println(x);
    11:      }
  12: }
  A: ==
  B: !=
  C: <>
  D: <
  E: <=
  F: >
  G: >=
解説
 7行目でa[i]をxに代入しているので、7が出力されるということは、a[2]かa[5]が出力されているのだ、ということがわかります。選択肢は比較演算子なので、要素の中で一番大きいものを求めているのでしょう。ということは、A、B、Cは除外されます。特にCはjavaにはありません。Basicをやっていた方気をつけて。

 xの初期値はa[0]です。この後6行目の条件が成立すれば入れ替えが起こるのですから、新しいa[i]はxより大きいはずです。よって正解はD。図に繰り返しの様子を示しました。細い矢印はxにa[i]が代入される様子を表します。赤い線は比較です。繰り返しでiが1の時には、a[1]の5とxが比較され、a[1]の方が大きいので、xの新しい値は5になります。次のi=2でも同じようなことが起こり、最終的にxの値はa[2]の7になります。


 ここで気を抜くと残念なことになります。もしかしたらa[5]の7が出力されているのかもしれません。i=5のときも入れ替えが行われるようにするには、xとa[i]が等しくても7行目が実行されるようにすればOKです。つまりEも正解になります。下の図のように青い部分が先ほどより余計な処理になります。ただ単に最大値を求めるだけならば、青い部分は必要ありません。


 本試験では、いくつ選択するかを指定してあるかもしれませんが、してないかもしれません。もしひとつだけ選んで安心してしまうといけないので、こんなひっかけを出しました。


解答 D E

参考 読み物Java 第7章 一軒家よりアパート? 
問題10(難易度:2)                                2004年12月1日
次をコンパイル、実行した結果、「7 5」と出力された。XXXの部分に入る演算子はどれか、下から選びなさい。

  1: public class Main {
    2:      public static void main(String[] args) {
    3:              int[] a = { 1, 5, 7, 2, 4, 7 };
    4:              int x = a[0], j = 0;
    5:              for (int i = 1; i < a.length; i++) {
    6:                      if (x XXX a[i]) {
    7:                              x = a[i];
    8:                              j = i;
    9:                      }
  10:               }
  11:               System.out.println(x + " " + j);
  12:        }
 13: }

          A: ==
        B: !=
        C: <>
        D: <
        E: <=
        F: >
        G: >=
解説
 前の問題9とほとんど同じですが、新たに変数jが登場します。7行目でxの値を変更するときに、添え字iの値をjに代入しています。つまり出力された最大値7はa[2]ではなく、a[5]の方であるということがわかります。前問題でもやったように、6行目でxとa[i]が等しい場合も、xの値を入れ替えることになります。よって正解はE。これで出力結果が「7 2」ならばDが正解になるでしょう。
 下に変数jの値の変化も図に合わせてみました。
解答 E

参考 読み物Java 第7章 一軒家よりアパート?
<<3.配列 の目次|次問題>>
Copyright (c) 2004 Nagi Imai All Rights Reserved..