[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIB(Javaプログラミング入門)第9回

目次
9.1 配列(1)
9.1.1 配列とは
9.1.2 配列の使い方
9.1.3 配列の初期化
9.1.4 配列と繰返し
9.1.5 配列の使用例
9.2 演習9
9.3 レポート課題
9.4 参考文献
索引
インデックス   初期化(配列の)   添字   配列   配列要素  

9.1 配列(1)

9.1.1 配列とは

変数を用いるとデータを一つ格納できることは、すでに学びました。 たくさんのデータを格納するには、データの個数だけ変数を用意すれば可能です。 しかし、それらのデータを系統的に取り扱うことは困難です。

配列array ) というものを用いると、たくさんのデータを系統的に格納することができます。 配列とは、データの「入れ物」が並んだものと考えてください。 次の図は、配列のイメージです。

配列のイメージ
図 9.1  配列のイメージ

「入れ物」の一つ一つを 配列要素array element ) とよびます。 配列には次のような特徴があります。

9.1.2 配列の使い方

変数を使うためには、変数の宣言が必要でした。 int x; のように変数を宣言すると、変数 x に整数( int 型)が一つ格納できました。

配列を使うためには、配列の宣言と配列の生成という二段階の手続きが必要です。 次のプログラムは、配列を宣言し、生成し、その3番目に整数23を格納し、それを出力するものです。

/*  1*/ class ArrayTest { // 配列のテスト
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] a; // 宣言
/*  4*/         a = new int[10]; // 10個生成
/*  5*/         a[3] = 23; // 3番目に格納
/*  6*/         System.out.println(a[3]); // 3番目を出力
/*  7*/     }
/*  8*/ }
asiaa1:~/comp2b k12x1001$ java ArrayTest
23
asiaa1:~/comp2b k12x1001$

整数( int 型)の場合、配列の宣言は次のように書きます。

int[] 配列;

ここで、「 配列 」は配列の名前です。 配列の生成は、

配列 = new int[要素数];

と書きます。 ここで、「 要素数 」は配列の要素数です。

上記のプログラムでは、3行目で名前が a である配列を宣言しています。 また、4行目で要素数が10である配列を生成しています。

配列要素にデータを格納するには、

配列[番号] = ;

と書きます。 「 配列 」の「 番号 」番目の要素に「 」の値を格納します。 ここで、「 番号 」は数そのものである必要はありません。 数を値に持つならば、変数や式でもかまいません。 例えば、変数 i の値が3で x の値が100ならば、 b[i - 1] = x + 1; によって配列 b の2番目の要素に101が格納されます。 式

配列[番号]

で、「 配列 」の「 番号 」番目の要素が取り出せます。 なお、配列の何番目の要素かを表すこの「 番号 」を、配列の 添字subscript ) 、または インデックスindex ) とよびます。

上記のプログラムでは、5行目で配列の3番目の要素にデータ23を格納しています。 また、6行目ではそのデータを取り出して出力しています。

上記のプログラムにおいて、 a [10] は存在しないことに注意してください。 このような、存在しない要素にデータを格納しようとしたり、データを取り出そうとすると、エラーが発生します。

/*  1*/ class ArrayError { // 配列のエラー
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] a;
/*  4*/         a = new int[10]; // 0番目から9番目まで
/*  5*/         a[10] = 100; // 10番目は存在しない
/*  6*/         System.out.println(100);
/*  7*/     }
/*  8*/ }
asiaa1:~/comp2b k12x1001$ java ArrayError
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
        at ArrayError.main(ArrayError.java:5)
asiaa1:~/comp2b k12x1001$

なお、配列の要素数をどこかに記録しておく必要はありません。 これは、式

配列.length

によっていつでも取り出せます。

注意: 教科書によっては、配列の宣言は

int a[];

などと書くと説明しています。 Javaでは、 int[] a;int a[]; は同じ意味です。 ただし、これらを混在させるのは混乱のもとですので、この授業では前者に統一します。

9.1.3 配列の初期化

上記のイメージの通り、配列にデータを格納しましょう。 これは、配列の宣言、配列の生成、配列要素への代入という手順を踏むとできます。 以下はそのようなプログラム(部分)です。

int[] a;
a = new int[10];
a[0] = 20; a[1] = 21; a[2] = 22; a[3] = 23; a[4] = 24;
a[5] = 25; a[6] = 26; a[7] = 27; a[8] = 28; a[9] = 29;

次のように書くと、配列の宣言と生成が同時に行えます。

int[] a = new int[10]; // 宣言と生成
a[0] = 20; a[1] = 21; a[2] = 22; a[3] = 23; a[4] = 24;
a[5] = 25; a[6] = 26; a[7] = 27; a[8] = 28; a[9] = 29;

さらに、データの格納も同時に行うことができます。 これは次のように書きます。

int[] a = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29};

このことを、配列の 初期化initialization ) とよびます。 配列の初期化では、キーワード new や配列の要素数は書きません。

9.1.4 配列と繰返し

配列のプログラムでは、繰返しを利用するのが普通です。 つまり、ループ制御変数 i を用意し、 for 文などの繰返しの中で、配列要素 a [ i ]からデータを取り出したり、 a [ i ]にデータを格納したりします。

次のプログラムは、配列 a の要素をすべて出力するものです。

/*  1*/ class ArrayPrint { // 配列の出力
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; // 初期化
/*  5*/         for (i = 0; i < a.length; i++) { // aの要素数回繰り返す
/*  6*/             System.out.println("a[" + i + "] = " + a[i]);
/*  7*/         }
/*  8*/     }
/*  9*/ }
asiaa1:~/comp2b k12x1001$ java ArrayPrint
a[0] = 20
a[1] = 21
a[2] = 22
a[3] = 23
a[4] = 24
a[5] = 25
a[6] = 26
a[7] = 27
a[8] = 28
a[9] = 29
asiaa1:~/comp2b k12x1001$

4行目で配列 a を初期化します。 式 a . length の値は10なので、5行目の for 文では変数 i は0から9まで動きます。 6行目で配列要素 a [ i ]の値を詳しく出力します。

9.1.5 配列の使用例

配列の使用例として、はじめに、配列要素の総和を求めます。

{100, 200, 100, 300, 200}

で表される配列の要素の合計を、レジの計算の要領で算出します。 つまり、

sum += a[0];
sum += a[1];
sum += a[2];
...

のように計算します。 プログラムは次の通りです。

/*  1*/ class ArraySummation { // 配列の総和
/*  2*/     public static void main (String[] args) {
/*  3*/         int i, sum = 0;
/*  4*/         int[] a = {100, 200, 100, 300, 200};
/*  5*/         for (i = 0; i < a.length; i++) {
/*  6*/             sum += a[i];
/*  7*/         }
/*  8*/         System.out.println("合計は" + sum);
/*  9*/     }
/* 10*/ }
asiaa1:~/comp2b k12x1001$ java ArraySummation
合計は900
asiaa1:~/comp2b k12x1001$

次の例は、配列要素の最大値を求めるものです。

{100, 200, 100, 300, 200}

で表される配列の要素の最大値は、人間が見れば 300 だと分かります。

この問題をコンピュータで解決するのに、勝ち抜き方式を使うことにします。 これは、はじめに最初の要素をとりあえずチャンピオンにします。 続いて、次の要素とチャンピオンが勝負をし、チャンピオンが負けたら勝者を新たにチャンピオンにします。 これを要素がなくなるまで繰り返します。 最後のチャンピオンが全体のチャンピオンであるというわけです。

具体的には、

max = a[0];
if (a[1] > max) {
    max = a[1];
}
if (a[2] > max) {
    max = a[2];
}
...

のようにして、最大値を求めます。 プログラムは次の通りです。

/*  1*/ class ArrayMaximum { // 配列の最大値
/*  2*/     public static void main (String[] args) {
/*  3*/         int i, max;
/*  4*/         int[] a = {100, 200, 100, 300, 200};
/*  5*/         max = a[0]; // とりあえずチャンピオンにする
/*  6*/         for (i = 1; i < a.length; i++) {
/*  7*/             if (a[i] > max) { // チャンピオンが負けたら
/*  8*/                 max = a[i]; // 勝者をチャンピオンにする
/*  9*/             }
/* 10*/         }
/* 11*/         System.out.println("最大値は" + max);
/* 12*/     }
/* 13*/ }
asiaa1:~/comp2b k12x1001$ java ArrayMaximum
最大値は300
asiaa1:~/comp2b k12x1001$

最後の例として、アンケートの集計を行います。 ある議題に関するアンケート調査を25人に対して行い、次のような回答(1=賛成、2=反対)が得られたとします。

2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1

この回答から、賛成が何人、反対が何人かを求めるプログラムを考えます。

まず、回答を格納する配列 answers を用意します。 配列の初期化を使って、これに回答を格納します。 そして、この配列から回答をひとつずつ取り出し、回答で場合分けをし、その人数を1増加させるという操作を繰り返して、回答ごとに人数を数えます。

/*  1*/ class YesNoQuestionnaire { // 賛成反対アンケート
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int yesCount = 0, noCount = 0; // 賛成の人数と反対の人数
/*  5*/         int[] answers = {
/*  6*/             2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 
/*  7*/             1, 2, 1, 1, 2, 1, 2, 2, 1, 2,
/*  8*/             1, 2, 1, 1, 1
/*  9*/         };
/* 10*/         for (i = 0; i < answers.length; i++) {
/* 11*/             switch (answers[i]) { // 回答で場合分け
/* 12*/                 case 1: yesCount++; break; // 賛成の場合
/* 13*/                 case 2: noCount++; break; // 反対の場合
/* 14*/                 default: System.out.println("エラー"); break;
/* 15*/             }
/* 16*/         }
/* 17*/         System.out.println("賛成" + yesCount + "人");
/* 18*/         System.out.println("反対" + noCount + "人");
/* 19*/     }
/* 20*/ }
asiaa1:~/comp2b k12x1001$ java YesNoQuestionnaire
賛成16人
反対9人
asiaa1:~/comp2b k12x1001$

9.2 演習9

ある会社のある課には社員が25人います。 社員の血液型を調べることになりました。 調査結果(1=A型、2=B型、3=O型、4=AB型)は次の通りです。

1, 3, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 2, 4, 2, 1, 1, 1, 1, 1, 2, 4, 3

このデータをプログラムの中に書き、配列の初期化の要領で配列に格納してください。 そして、それぞれの血液型の人数を数えて出力するプログラムを作成してください。

asiaa1:~/comp2b k12x1001$ java BloodTypeQuestionnaire
A型10人
B型11人
O型2人
AB型2人
asiaa1:~/comp2b k12x1001$

余力のある人は、割合を計算して出力してください。

ヒント: 人数は整数なのに対して割合は実数なので、人数を実数にキャストするか、数式に現れる数値を実数で表現するかして、実数で割合の計算をしてください。

asiaa1:~/comp2b k12x1001$ java BloodTypeQuestionnaire2
A型10人(40.0%)
B型11人(44.0%)
O型2人(8.0%)
AB型2人(8.0%)
asiaa1:~/comp2b k12x1001$

9.3 レポート課題

今日の演習9の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(k12x1001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(6月15日)を明記してください。


9.4 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2012年6月15日更新
小西 善二郎 <konishi@cis.twcu.ac.jp>
Copyright (C) 2012 Zenjiro Konishi. All rights reserved.