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

情報処理IIIA(Javaプログラミング入門)第6回

目次 索引
6.1 データの出力(1)
6.1.1 文字列の連結
6.2 配列
6.2.1 配列とは
6.2.2 配列の使い方
6.2.3 配列の初期化
6.2.4 配列のコピー
6.2.5 配列の使用例
6.3 演習6
6.4 レポート課題
インデックス  初期化(配列の)  添字  配列  配列要素 

6.1 データの出力(1)

6.1.1 文字列の連結

これまで、端末エミュレータにデータを出力するには、 System.out.println( data ); を使ってきました。 文字列をそのまま出力するには、 data の部分にその文字列をダブルクオート( " )で囲んで書き、変数の値を出力するには、そこにその変数名を書きました。 演算子 + で結びますと、それらを混在させることができます。

/* 1*/ class IntToString {
/* 2*/     public static void main (String[] args) {
/* 3*/         int x = 100;
/* 4*/         System.out.println("x");
/* 5*/         System.out.println(x);
/* 6*/         System.out.println("x is " + x);
/* 7*/     }
/* 8*/ }
b00a001@Ampere:~/java% java IntToString
x
100
x is 100
b00a001@Ampere:~/java%

実は、この演算子 + は文字列の連結です。 一方だけが文字列のときは、他方を文字列に変換して連結するという約束になっています。 整数と整数の足し算も + ですので、混乱しそうでしたら括弧を使ってください。

System.out.println( data ); は、出力の後に改行します。 改行してほしくないときは、 System.out.print( data ); と書きます。 また、改行だけしてほしいときは、 System.out.println(); とします。

注意: 端末エミュレータへの出力は一文字ずつ行なわれるわけではなく、ある程度の文字数になるか改行があるとまとめて行なわれます。 System.out.print( data ); と書いてあるのに何も出力されないときは、改行 System.out.println(); を忘れていないか確認してください。


6.2 配列

6.2.1 配列とは

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

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

An image of an array
図 6.1  配列のイメージ

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

6.2.2 配列の使い方

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

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

/* 1*/ class ArrayTest {
/* 2*/     public static void main (String[] args) {
/* 3*/         int[] a;
/* 4*/         a = new int[10];
/* 5*/         a[3] = 72;
/* 6*/         System.out.println(a[3]);
/* 7*/     }
/* 8*/ }
b00a001@Ampere:~/java% java ArrayTest
72
b00a001@Ampere:~/java%

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

int[] arrayname;

ここで、 arrayname は配列の変数名です。 配列の生成は、

arrayname = new int[size];

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

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

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

arrayname[index] = expression;

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

arrayname[index]

は、配列の index 番目の要素に格納されたデータを値とします。 なお、配列の何番目の要素かを表すこの式 index を、配列の 添字subscript ) 、または インデックスindex ) とよびます。

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

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

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

arrayname.length

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

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

int a[];

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

6.2.3 配列の初期化

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

int[] a;
a = new int[10];
a[0] = 99; a[1] = 90; a[2] = 81; a[3] = 72; a[4] = 63;
a[5] = 54; a[6] = 45; a[7] = 36; a[8] = 27; a[9] = 18;

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

int[] a = new int[10];
a[0] = 99; a[1] = 90; a[2] = 81; a[3] = 72; a[4] = 63;
a[5] = 54; a[6] = 45; a[7] = 36; a[8] = 27; a[9] = 18;

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

int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18};

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

6.2.4 配列のコピー

整数( int 型)の変数 x から変数 y にコピーするには、代入文 y = x; でできます。 しかし、配列の変数 a の要素から変数 b の要素にコピーするには、 b = a; ではできません。 一つ一つ配列要素をコピーする必要があります。

次のプログラムは、配列 a の要素から配列 b の要素にコピーし、 b の要素を出力するものです。

/* 1*/ class ArrayCopy {
/* 2*/     public static void main (String[] args) {
/* 3*/         int i;
/* 4*/         int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18};
/* 5*/         int[] b = new int[a.length];
/* 6*/         for (i = 0; i < a.length; i++) {
/* 7*/             b[i] = a[i];
/* 8*/         }
/* 9*/         for (i = 0; i < b.length; i++) {
/*10*/             System.out.println("b[" + i + "] is " + b[i]);
/*11*/         }
/*12*/     }
/*13*/ }
b00a001@Ampere:~/java% java ArrayCopy
b[0] is 99
b[1] is 90
b[2] is 81
b[3] is 72
b[4] is 63
b[5] is 54
b[6] is 45
b[7] is 36
b[8] is 27
b[9] is 18
b00a001@Ampere:~/java%

5行目で、配列 a と同じ要素数の配列 b を宣言し、生成します。 6行目から8行目でコピーが行われます。 式 a.length の値は10ですので、6行目の for 文では変数 i は0から9まで動きます。 これは、配列 a (および配列 b )の添字の範囲と一致します。 9行目から11行目で配列 b の要素を詳しく出力します。

6.2.5 配列の使用例

配列の使用例として、はじめに二つの配列の連結を行います。

{10, 20, 30, 40, 50}

で表される配列と

{60, 70, 80}

で表される配列から、

{10, 20, 30, 40, 50, 60, 70, 80}

で表される配列を作ります。 これは、結果の配列を生成し、その左側にコピーした後、右側にコピーするとできます。 右側のコピーは、左側の要素数だけずらして行うことに気をつけてください。

アルゴリズムは次のようになります。

  1. ループ制御変数 i を宣言する。
  2. 左側の配列の変数 a を宣言し、初期値を 10, 20, 30, 40, 50 とする。
  3. 右側の配列の変数 b を宣言し、初期値を 60, 70, 80 とする。
  4. 結果の配列の変数 c を宣言し、 a の要素数と b の要素数を合計した要素数を持つ配列を生成し、 c の値をそれとする。
  5. i の値を 0 から a の要素数未満の間増加させながら、以下を繰り返す。{
  6.    a [ i ] から c [ i ] にコピーする。
  7. i の値を 0 から b の要素数未満の間増加させながら、以下を繰り返す。{
  8.    b [ i ] から c [ i + a の要素数] にコピーする。
  9. i の値を 0 から c の要素数未満の間増加させながら、以下を繰り返す。{
  10.    c [ i ] の値を詳しく出力する。

プログラムは以下のようになります。

/* 1*/ class ArrayAppend {
/* 2*/     public static void main (String[] args) {
/* 3*/         int i;
/* 4*/         int[] a = {10, 20, 30, 40, 50};
/* 5*/         int[] b = {60, 70, 80};
/* 6*/         int[] c = new int[a.length + b.length];
/* 7*/         for (i = 0; i < a.length; i++) {
/* 8*/             c[i] = a[i];
/* 9*/         }
/*10*/         for (i = 0; i < b.length; i++) {
/*11*/             c[i + a.length] = b[i];
/*12*/         }
/*13*/         for (i = 0; i < c.length; i++) {
/*14*/             System.out.println("c[" + i + "] is " + c[i]);
/*15*/         }
/*16*/     }
/*17*/ }
b00a001@Ampere:~/java% java ArrayAppend
c[0] is 10
c[1] is 20
c[2] is 30
c[3] is 40
c[4] is 50
c[5] is 60
c[6] is 70
c[7] is 80
b00a001@Ampere:~/java%

次の例は、配列の逆転を求めるものです。

{10, 20, 30, 40, 50}

で表される配列から

{50, 40, 30, 20, 10}

で表される配列を作ります。 これは、もとの配列の右から i 番目を、結果の配列の左から i 番目にコピーすればできます。 0番目から数えることに気をつけますと、右から i 番目は左から「要素数 - 1 - i 」番目であることが分かります。

アルゴリズムは次のようになります。

  1. ループ制御変数 i を宣言する。
  2. もとの配列の変数 a を宣言し、初期値を 10, 20, 30, 40, 50 とする。
  3. 結果の配列の変数 b を宣言し、 a の要素数と同じ要素数を持つ配列を生成し、 b の値をそれとする。
  4. i の値を 0 から a の要素数未満の間増加させながら、以下を繰り返す。{
  5.    a [ a の要素数 - 1 - i ] から b [ i ] にコピーする。
  6. i の値を 0 から b の要素数未満の間増加させながら、以下を繰り返す。{
  7.    b [ i ] の値を詳しく出力する。

プログラムは以下のようになります。

/* 1*/ class ArrayReverse {
/* 2*/     public static void main (String[] args) {
/* 3*/         int i;
/* 4*/         int[] a = {10, 20, 30, 40, 50};
/* 5*/         int[] b = new int[a.length];
/* 6*/         for (i = 0; i < a.length; i++) {
/* 7*/             b[i] = a[a.length - 1 - i];
/* 8*/         }
/* 9*/         for (i = 0; i < b.length; i++) {
/*10*/             System.out.println("b[" + i + "] is " + b[i]);
/*11*/         }
/*12*/     }
/*13*/ }
b00a001@Ampere:~/java% java ArrayReverse
b[0] is 50
b[1] is 40
b[2] is 30
b[3] is 20
b[4] is 10
b00a001@Ampere:~/java%

次の例は、配列要素の総和を求めるものです。

{100, 200, 100, 300, 200}

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

アルゴリズムは次のようになります。

  1. ループ制御変数 i を宣言する。
  2. 総和を表す変数 sum を宣言し、初期値を 0 とする。
  3. 配列の変数 a を宣言し、初期値を 100, 200, 100, 300, 200 とする。
  4. i の値を 0 から a の要素数未満の間増加させながら、以下を繰り返す。{
  5.    sum の値を a [ i ] 増やす。
  6. sum の値を詳しく出力する。

プログラムは以下のようになります。

/* 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 = sum + a[i];
/* 7*/         }
/* 8*/         System.out.println("The sum is " + sum);
/* 9*/     }
/*10*/ }
b00a001@Ampere:~/java% java ArraySummation
The sum is 900
b00a001@Ampere:~/java%

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

{100, 200, 100, 300, 200}

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

アルゴリズムは次のようになります。

  1. ループ制御変数 i を宣言する。
  2. 最大値を表す変数 max を宣言する。
  3. 配列の変数 a を宣言し、初期値を 100, 200, 100, 300, 200 とする。
  4. max の値を、とりあえず a [0] とする。
  5. i の値を 1 から a の要素数未満の間増加させながら、以下を繰り返す。{
  6.   もし a [ i ] が max より大きいならば、{
  7.      max の値を a [ i ] に変更する。
  8.   }
  9. max の値を詳しく出力する。

プログラムは以下のようになります。

/* 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("The maximum value is " + max);
/*12*/     }
/*13*/ }
b00a001@Ampere:~/java% java ArrayMaximum
The maximum value is 300
b00a001@Ampere:~/java%

6.3 演習6

ある株式会社の株価が最近10日間で以下のように変動したとします。 この株価をリストアップするプログラムを作成してください。 ただし、この期間の最高値と最安値を計算しておき、最高値には記号"H", 最安値には記号"L"を追加するものとします。 (株価が変わりませんと、最高値と最安値は等しくなりますが、そのようなことは起こらないと仮定します。)

表 6.1  ある株式会社の株価の変動
株価(円) 340 350 340 310 350 370 350 350 370 340
b00a001@Ampere:~/java% java StockPrice
340 
350 
340 
310L
350 
370H
350 
350 
370H
340 
b00a001@Ampere:~/java%

アルゴリズムは次のようにします。

  1. ループ制御変数 i , 最高値を表す変数 high , 最安値を表す変数 low をそれぞれ宣言する。
  2. 株価を表す配列の変数 price を宣言し、初期値を 340, 350, 340, 310, 350, 370, 350, 350, 370, 340 とする。
  3. high の値を、とりあえず price [0] とする。
  4. i の値を 1 から price の要素数未満の間増加させながら、以下を繰り返す。{
  5.   もし price [ i ] が high より大きいならば、{
  6.      high の値を price [ i ] に変更する。
  7.   }
  8. low の値を、とりあえず price [0] とする。
  9. i の値を 1 から price の要素数未満の間増加させながら、以下を繰り返す。{
  10.   もし price [ i ] が low より小さいならば、{
  11.      low の値を price [ i ] に変更する。
  12.   }
  13. i の値を 0 から price の要素数未満の間増加させながら、以下を繰り返す。{
  14.    price [ i ] の値を改行なしで出力する。
  15.   もし price [ i ] が high と等しいならば、{
  16.     "H"を出力する。
  17.   }そうでなくて、 price [ i ] が low と等しいならば、{
  18.     "L"を出力する。
  19.   }どれでもないならば、{
  20.     " "を出力する。
  21.   }

なお、プログラムを入力する際には以下をコピーアンドペーストするとよいでしょう。

{340, 350, 340, 310, 350, 370, 350, 350, 370, 340}

余力のある人は、前日比も追加してください。 前日比は括弧内に書くことにします。 株価が上昇したときの符号"+"を忘れないでください。

b00a001@Ampere:~/java% java StockPrice2
340 
350  (+10)
340  (-10)
310L (-30)
350  (+40)
370H (+20)
350  (-20)
350  (+0)
370H (+20)
340  (-30)
b00a001@Ampere:~/java%

6.4 レポート課題

今日の演習6に従ってJavaプログラムを作成し、そのプログラムをkonishi@twcu.ac.jpあてにメールで提出してください。 メールには、学生番号、氏名、科目名、授業日(10/31)を明記してください。


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

2002年10月31日更新
konishi@twcu.ac.jp
Copyright (C) 2002 Zenjiro Konishi. All rights reserved.