目次 | 索引 |
---|---|
前回の授業では、選択というプログラムの構成要素を紹介しました。 今日は、 反復 ( iteration ) について説明します。 反復を表す文は、 繰返し文 ( repetitive statement ) 、または ループ文 ( loop statement ) とよばれます。
反復にはいくつか種類がありますが、「何々が成り立つ間、何々を繰り返す」というものが基本です。
この種の反復には
while文
(
while statement
)
を使います。
while
文は以下の形をとります。
while (condition) { statement; ... }
条件
condition
が成り立っている間、文
statement
;
...
が繰り返し実行されます。
ここで、Good afternoon!と10回出力するプログラムを考えます。
はじめは数え上げ方式です。
これは、変数
i
に0を代入しておき、Good afternoon!と一回出力するごとに
i
の値を1増やすということを、
i
の値が10未満の間繰り返すものです。
/* 1*/ class TenAfternoons { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ i = 0; /* 5*/ while (i < 10) { /* 6*/ System.out.println("Good afternoon!"); /* 7*/ i++; /* 8*/ } /* 9*/ } /* 10*/ }
b04a001@AsiaA1:~/java% java TenAfternoons Good afternoon! Good afternoon! Good afternoon! Good afternoon! Good afternoon! Good afternoon! Good afternoon! Good afternoon! Good afternoon! Good afternoon! b04a001@AsiaA1:~/java%
5行目から8行目までの
while
文は次のように実行されます。
i
の値は0。条件i < 10
が成り立つので、Good afternoon!と出力し、i
の値を1増やす。i
の値は1。条件i < 10
が成り立つので、Good afternoon!と出力し、i
の値を1増やす。i
の値は9。条件i < 10
が成り立つので、Good afternoon!と出力し、i
の値を1増やす。i
の値は10。条件i < 10
は成り立たないので、このwhile
文の実行を終える。
次はカウントダウン方式です。
これは、変数
i
に10を代入しておき、Good afternoon!と一回出力するごとに
i
の値を1減らすということを、
i
の値が正の間繰り返すものです。
/* 1*/ class TenAfternoons2 { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ i = 10; /* 5*/ while (i > 0) { /* 6*/ System.out.println("Good afternoon!"); /* 7*/ i--; /* 8*/ } /* 9*/ } /* 10*/ }
5行目から8行目までの
while
文は次のように実行されます。
i
の値は10。条件i > 0
が成り立つので、Good afternoon!と出力し、i
の値を1減らす。i
の値は9。条件i > 0
が成り立つので、Good afternoon!と出力し、i
の値を1減らす。i
の値は1。条件i > 0
が成り立つので、Good afternoon!と出力し、i
の値を1減らす。i
の値は0。条件i > 0
は成り立たないので、このwhile
文の実行を終える。数え上げ方式とカウントダウン方式のどちらがよいかは、問題によって変わります。 数え上げ方式のほうがよく使われますが、カウントダウン方式が適切な場合もあります。
注意: 上記のプログラムで、7行目を書き忘れたとしましょう。
/* 1*/ class InfiniteAfternoons { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ i = 10; /* 5*/ while (i > 0) { /* 6*/ System.out.println("Good afternoon!"); /* 7*/ } /* 8*/ } /* 9*/ }
このプログラムを実行しますと、変数
i
の値は10のままですので、条件
i > 0
がずっと成り立ち、永遠にGood afternoon!と出力され続けることになります。
このような、いつまでも続く繰り返しを、
無限ループ
(
infinite loop
)
とよびます。
反復を使うときは、無限ループにならないように気をつける必要があります。
なお、誤って無限ループに陥ったときは、Ctrl-Cで強制終了してください。
注意: 繰り返しの回数を0にしますと、0回繰り返す、つまり、一度も実行されなくなります。
/* 1*/ class NoAfternoons { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ i = 0; /* 5*/ while (i < 0) { /* 6*/ System.out.println("Good afternoon!"); /* 7*/ i++; /* 8*/ } /* 9*/ } /* 10*/ }
このプログラムを実行しますと、条件
i < 0
は初めから成り立ちませんので、何も出力されないのです。
反復の種類の中には、繰り返す回数が明確なものがあります。
この場合、
ループ制御変数
(
loop control variable
)
とよばれる変数を増加(あるいは減少)させながら繰り返すのが一般的です。
for文
(
for statement
)
を用いますと、このような反復をコンパクトに書き表すことができます。
for
文は次のような形をとります。
for (statement1; condition; statement2) { statement3; ... }
まず文
statement1
が一度だけ実行されます。
そして条件
condition
が成り立っている間、文
statement3
;
...
と
statement2
が繰り返し実行されます。
while
文を使ってこの
for
文を書きますと、次のようになります。
statement1; while (condition) { statement3; ... statement2; }
for
文を用いますと、Good afternoon!と10回出力するプログラムは次のように書けます。
数え上げ方式については、
/* 1*/ class TenAfternoons3 { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ for (i = 0; i < 10; i++) { /* 5*/ System.out.println("Good afternoon!"); /* 6*/ } /* 7*/ } /* 8*/ }
です。 カウントダウン方式は、
/* 1*/ class TenAfternoons4 { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ for (i = 10; i > 0; i--) { /* 5*/ System.out.println("Good afternoon!"); /* 6*/ } /* 7*/ } /* 8*/ }
となります。
while
文と
for
文には本質的な差はありません。
繰返しの回数がはっきりしているときには
for
文、そうでないときには
while
文を使うのがよいでしょう。
反復の使用例として、はじめに 1+2+…+100 の計算を行います。
この問題は、レジの計算をまねることで解決できます。 つまり、それまでの合計を表す変数 sum を用意して、初期値を 0 とします。 そして、 sum の値を 1 増やし、2 増やし、…と繰り返し、100 増やした時点の sum の値が答になるわけです。 アルゴリズムは次のようになります。
プログラムは以下のようになります。
/* 1*/ class Summation100 { /* 2*/ public static void main (String[] args) { /* 3*/ int i, sum = 0; /* 4*/ for (i = 1; i <= 100; i++) { /* 5*/ sum = sum + i; /* 6*/ } /* 7*/ System.out.println(sum); /* 8*/ } /* 9*/ }
b04a001@AsiaA1:~/java% java Summation100 5050 b04a001@AsiaA1:~/java%
次の例は、360 の約数をすべて求めるものです。
360 の約数が、1 から 360 までの間にあることは、数学的に分かっています。 したがって、1 から 360 までの数一つ一つに対して、360 がその数で割り切れるかどうかを判断すれば、約数がもれなく見つけられます。 アルゴリズムは次のようになります。
プログラムは以下のようになります。
/* 1*/ class Divisors360 { /* 2*/ public static void main (String[] args) { /* 3*/ int i; /* 4*/ for (i = 1; i <= 360; i++) { /* 5*/ if (360 % i == 0) { /* 6*/ System.out.println(i); /* 7*/ } /* 8*/ } /* 9*/ } /* 10*/ }
b04a001@AsiaA1:~/java% java Divisors360 1 2 3 4 5 6 8 9 10 12 15 18 20 24 30 36 40 45 60 72 90 120 180 360 b04a001@AsiaA1:~/java%
最後の例は、塗り潰した正方形を描くアプレットです。
塗り潰した正方形(長方形)を描くには、
g.fillRect(
...
);
を使うことはすでに説明しました。
ここではこれを用いず、自分で正方形を塗り潰すことにします。
例として、授業で最初に紹介したアプレットを考えます。
/* 1*/ import java.applet.*; /* 2*/ import java.awt.*; /* 3*/ /* 4*/ public class BlackBox extends Applet { /* 5*/ public void paint (Graphics g) { /* 6*/ g.setColor(Color.black); /* 7*/ g.fillRect(50, 50, 100, 100); /* 8*/ } /* 9*/ }
正方形は、上から順にすきまなく水平線を引いていけば、塗り潰すことができます。 この場合は、
g.fillRect(50, 50, 100, 100);
の代わりに
g.drawLine(50, 50, 150, 50); g.drawLine(50, 51, 150, 51); g.drawLine(50, 52, 150, 52); ... g.drawLine(50, 150, 150, 150);
を実行すればよいわけです。
アルゴリズムは次のようになります。
プログラムは以下のようになります。
/* 1*/ import java.applet.*; /* 2*/ import java.awt.*; /* 3*/ /* 4*/ public class FillSquare extends Applet { /* 5*/ public void paint (Graphics g) { /* 6*/ int i; /* 7*/ for (i = 0; i <= 100; i++) { /* 8*/ g.drawLine(50, 50 + i, 150, 50 + i); /* 9*/ } /* 10*/ } /* 11*/ }
正方形は、左から順に垂直な線を引いても塗り潰せます。 上記の正方形ですと、
g.fillRect(50, 50, 100, 100);
の代わりに
g.drawLine(50, 50, 50, 150); g.drawLine(51, 50, 51, 150); g.drawLine(52, 50, 52, 150); ... g.drawLine(150, 50, 150, 150);
を実行することになります。
アルゴリズムは次のようになります。
プログラムは以下のようになります。
/* 1*/ import java.applet.*; /* 2*/ import java.awt.*; /* 3*/ /* 4*/ public class FillSquare2 extends Applet { /* 5*/ public void paint (Graphics g) { /* 6*/ int i; /* 7*/ for (i = 0; i <= 100; i++) { /* 8*/ g.drawLine(50 + i, 50, 50 + i, 150); /* 9*/ } /* 10*/ } /* 11*/ }
以下の幾何学模様を
for
文を用いて描きます。
この模様は、
g.drawRect(10, 10, 180, 180); g.drawRect(20, 20, 160, 160); g.drawRect(30, 30, 140, 140); ... g.drawRect(90, 90, 20, 20);
を実行すれば描けます。
アルゴリズムは次のようにします。
このアルゴリズムをプログラムにしてください。
余力のある人は、以下の幾何学模様を
for
文を用いて描いてください。
今日の演習5に従ってJavaプログラムを作成し、そのプログラムをkonishi@twcu.ac.jpあてにメールで提出してください。 メールには、学生番号、氏名、科目名、授業日(5/14)を明記してください。