○プログラミングに際して,繰返しの部分を書くときの考え方の例


繰返し処理になるプログラムを書くときの考え方を示す。本来,次のように考えな がらプログラミングされていると思うが,初心者から初級・中級になると,この思考段階は意識に上らずにプログラミングできるようになる。囲碁将棋でも初 級・中級になるに従って定石を踏み,5手先を読むのに似ているのだろう。

場合1 プログラムを書く時点で,何回繰り返すのかわかる時の繰返し処理の記述

forループを用いる。n回繰り返すものとすると

int i;

for (i=0;i<n;i++) {
  処理1;
  処理2;
  処理3;
  処理4;
  処理5;
  処理6;
  処理7;
}

場合2 順に処理を書いていったら,ある条件が成り立ったら,上の方の処理のところまで戻りたくなった。

処理1;
処理2;
処理3;
処理4;
処理5;
処理6;
処理7;

処理7を終えたところで,処理2と処理3の間に戻り,
処理3から処理7までを繰返し処理したくなったとすると,
ここにループ(繰返し処理)が必要だということになる。

  処理1;
  処理2;
 →処理3;
↑ 処理4;
↑ 処理5;
↑ 処理6;
↑ 処理7;
 ←


右のように記述する

処理1;
処理2;
do {
  処理3;
  処理4;
  処理5;
  処理6;
  処理7;
} while (繰返しをしたい条件);

場合2の変形 さらによく考えたら,処理3から処理7は一度も行なわれない可能性もある場合は判定部が繰返し処理の先頭になり次のようになることもある。(経験値があがると最初からこのように書けるようになる)

処理1;
処理2;
while (繰返しを継続する条件) {
  処理3;
  処理4;
  処理5;
  処理6;
  処理7;
}

場合3 順に処理を書いていったら,「もし〜が成り立ったら‥‥‥‥を繰返し行なう」という処理になった。

例えば,処理3と処理4の間で条件のチェックを入れたい場合は次のようになるが,
処理7までで「繰返して欲しい処理」すべてが終わった後の希望で次の2つの場合に分かれる。

処理1;
処理2;
処理3;
while (繰返し条件) {
  処理4;
  処理5;
  処理6;
  処理7;

場合3.1
処理7の後,繰返し条件が成立している間,
処理4から繰り返したい場合
  処理1;
  処理2;
  処理3;
  while (繰返し条件) {
 →  処理4;
↑   処理5;
↑   処理6;
 ←  処理7;

この場合は素直にwhileループを終わればよいので
次のようになる。
処理1;
処理2;
処理3;
while (繰返し条件) {
  処理4;
  処理5;
  処理6;
  処理7;
}
場合3.2
処理7の後,処理2まで戻って繰り返したくなった時
  処理1;
 →処理2;
↑ 処理3;
↑ while (繰返し条件) {
↑   処理4;
↑   処理5;
↑   処理6;
 ←  処理7;

処理7の後に,処理2・処理3を記述してからwhileループを終わればよい
処理1;
処理2;
処理3;
while (繰返し条件) {
  処理4;
  処理5;
  処理6;
  処理7;
  処理2
  処理3
}

例1 List 2.3.1で粘り強く再入力を強制する仕組みを作る時

作業1 まずやりたいことを順に書く

処理1:「正整数を入力してください 」と表示
処理2:正整数をキーボード入力

作業2 処理2がすんだ時点で正整数でなかったらもう一度処理1からやり直したい。そこで

do {
    処理1:「正整数を入力してください 」と表示
    処理2:整数をキーボード入力
} while (入力された整数が0以下だったら);

となる
作業3 このdo-whileループは少なくとも1度は実行されなければならないため,whileループにはならない。

例2 List 2.2.1で何回割り切れるか数える仕組みを作る時

作業1 まずやりたいことを順に書く

処理1:nに入力値を設定
処理2:割り算回数カウンタ値を0にする
処理3:変数の状況を表示(これはしなくてもよい)

作業2 ここで繰返し作業を行ないたいのでwhile ()の文を書いてゆく

処理1:nに入力値を設定
処理2:割り算回数カウンタ値を0にする
処理3:変数の状況を表示(これはしなくてもよい)
while (n%2==0) {
  処理4:n=n/2を計算
  処理5:割り算回数カウンタ値を1増加
  処理6:変数の状況を表示(これはしなくてもよい)

作業3 処理6がすんだ時点で,条件を満たすなら,処理4から処理6を繰り返したいので素直にwhileループを閉じる

処理1:nに入力値を設定
処理2:割り算回数カウンタ値を0にする
処理3:変数の状況を表示(これはしなくてもよい)
while (n%2==0) {
  処理4:n=n/2を計算
  処理5:割り算回数カウンタ値を1増加
  処理6:変数の状況を表示(これはしなくてもよい)
}

例3 「ある数が2で何回割り切れるか」を求めるプログラムで,1つの数についての処理が終わったら,別の数に ついても処理するようにして,この処理を何回でも続けてきるようにしたい。なお,「ある数のキーボード入力」時点で,負の数が入力されたらプログラムが終 了するようにしたい。

作業1 まずやりたいことを順に書く

処理1:キーボードからnumberに数値を入力する

作業2 ここでnumberが正だったら繰返し作業を行ないたいのでwhile ()の文を書いてゆく

処理1:キーボードからnumberに数値を入力する
while (0<number) {
  処理2:numberについて,2で何回割り切れるかのブロック処理(複数の処理)
  処理3:求められた回数を表示する

作業3 ここで次の作業はキーボードから次のnumberを読み込みたいので処理1のところに戻りたいと考える。
しかし,処理1に戻るのではなく,処理3の次にもう一度,処理1を書いてからwhileループを閉じればよい。

処理1:キーボードからnumberに数値を入力する
while (0<number) {
  処理2:numberについて,2で何回割り切れるかのブロック処理(複数の処理)
  処理3:求められた回数を表示する
  処理1:キーボードからnumberに数値を入力する (次の作業のため)
}

プログラム例

import java.util.*;  // StringTokenizer
import java.io.*;    // BufferedReader

public class XXXX {
    public static void main(String[] args) {
        XXXX mainprg = new XXXX();
    }
   
   
XXXX() {
   
    int number,n,counter;
        number=getInt("正整数を入力してください ");
   
    while (0<number) {
            n=number;
            counter=0;
            System.out.printf("number=%d counter=%d\n",number,counter);
    
        while (n%2==0) {
        
        n=n/2;
           
    counter++;
        
        System.out. printf("n=%d counter=%d\n",n,counter);
       
    }
       
    System.out.printf("%dは%d回,2で割ることが出来ました\n",number,counter);
            number=getInt("正整数を入力してください ");
        }
    }

    private int getInt(String prompt){
        BufferedReader bffrd = new BufferedReader(new InputStreamReader(System.in));
        int ret=0;
        System.out.print(prompt);
        try {
            ret = Integer.valueOf(bffrd.readLine()).intValue();
        }
        catch(IOException e) {
            System.out.println("IO Error");
            System.exit(1);
        }
        return ret;
    }
}


/*
正整数を入力してください 24
number=24 counter=0
n=12 counter=1
n=6 counter=2
n=3 counter=3
24は3回,2で割ることが出来ました
正整数を入力してください 66
number=66 counter=0
n=33 counter=1
66は1回,2で割ることが出来ました
正整数を入力してください -1
*/