プログラム作成のヒント

与えられた正整数nは何回2で割ることができるかを調べるプログラムをつくる時の考え方をみてみよう。プログラムとは,コンピュータに与える手順書なので,人間に手順書を与える場合から考えてみよう。

1.中学生くらいの人間に指示する時
「与えられた正整数を2で割る作業を繰り返して,割り切れた回数を数えなさい。」
これで大丈夫でしょう。

2.小学生に指示するならどうする。
「与えられた正整数を2で割る作業を繰り返して,割り切れた回数を数えなさい。」
小学生だと,割り算に熱中するあまり,割り切れた回数を数えるのがおろそかになって,結局何回割り切れたか覚えていないかも知れない。
小学生を2人連れて来て,1人に割り算を連続してやらせ,もう1人に回数を数えさせたらうまく行くかもしれない。

3.コンピュータに指示する(Cプログラミング)
コンピュータに指示を出すなら,次のように指示しないといけない。コンピュータは計算は得意だが,手順についてはすべて教えてあげなければならない。小学生のように,「正整数を2で割る作業を繰り返して」というような指示はできない。

割り算する変数nとカウンタ変数counterを使う。(2人に小学生に対応)
正整数nをキーボードから取得する。
回数カウンタcounterを0にする。(小学生ならこの指示を与えなくても最初は0に決まっている)
nが2で割り切れるかどうか考える
 割り切れなかったら回数カウンタの値を表示して終わり
 割り切れるなら{ n=n/2 counter++ }
nが2で割り切れるかどうか考える
 割り切れなかったら回数カウンタの値を表示して終わり
 割り切れるなら{ n=n/2 counter++ }
nが2で割り切れるかどうか考える
 割り切れなかったら回数カウンタの値を表示して終わり
 割り切れるなら{ n=n/2 counter++ }
nが2で割り切れるかどうか考える
 割り切れなかったら回数カウンタの値を表示して終わり
 割り切れるなら{ n=n/2 counter++ }
nが2で割り切れるかどうか考える
 割り切れなかったら回数カウンタの値を表示して終わり
 割り切れるなら{ n=n/2 counter++ }
         :

ここでループの存在に気づいて

正整数nをキーボードから取得する
回数カウンタcounterを0にする
nが2で割り切れるかどうか考える 割り切れたら次の動作を繰り返す そうでなかったら回数カウンタの値を表示して終わり

  n=n/2
  counter++


ループとループ修了後の作業を分離して考えて

正整数nをキーボードから取得する
回数カウンタcounterを0にする
nが2で割り切れるかどうか考える 割り切れたら次の動作を繰り返す

  n=n/2
  counter++

回数カウンタcounterの値を表示する
終わり

whileの文法に則して書き直し

正整数nをキーボードから取得する
回数カウンタcounterを0にする
while (n%2==0)

  n=n/2
  counter++

回数カウンタcounterの値を表示する
終わり

回数カウンタの表示の時に,入力された値を表示したいが,nは変化してしまう。
そこで,別な変数に入力した値を覚えておいてもらうことを考える。
このために変数numberを導入する(3人目の中学生に対応かな)

正整数numberをキーボードから取得する
n=number
回数カウンタcounterを0にする
while (n%2==0)

  n=n/2
  counter++

最初の値numberと回数カウンタcounterの値を表示する
終わり

後はCの文法によってすべて書き直すとよい。

/*numberは2で割ることが何回出来るか*/
/*While0.java by Kosaka*/

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

public class While0 {
    public static void main(String[] args) {
        While0 mainprg = new While0();
    }
   
    While0() {
        int number,n,counter;
        number=getInt("正整数を入力してください ");
        n=number;
        counter=0; /*2で割り切れた回数を覚えている変数を0にする*/
        System.out.printf("number=%d counter=%d\n",number,counter);
        while (n%2==0) { /*2で割り切れたら中に入る*/
            n=n/2; /*割り切れることがわかっているので,実際に割り算する*/
            counter++; /*割り切れたので回数を覚えている変数の値を1増やす*/
            System.out.printf("n=%d counter=%d\n",n,counter);
        }
        System.out.printf("%dは%d回,2で割ることが出来ました\n",number,counter);
    }

    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;
    }
}

できあがり。