演習
½正整数 の値をキーボードから入力し、 なる各整数に対して
の値 を一覧表の形で出力するプログラムを作成せよ。作成したプログラムが、正しい答えを出す 最大の の値を調べ、その理由を説明せよ。
【コメント】
題意を理解していない例: キーボードから入力した に対して、
だけを出力し ている。
Σ
漸化式を用いた計算で、
の初期値をでは無くにしているため、値が正解より大き くなっている例があった。このような間違いは、プログラムの出力をチェックしていれば簡 単に見つかったはずである。
計算は出来ているが出力が見にくい例:
一応見易いと思われる出力の例:
整数を縦に並べる時最下位の桁を揃える右揃えという習慣に基づいた見易い例:
演習資料のプログラム例を実行していれば、このような形の出力が求められている事が分か るはずである。
上記の実行例では、 まで正しい答えが求まっている。( なので、は
より少なくとも倍以上大きくなるはずであるが、この例ではそうなっていない。従っ て明らかにの値は間違っている。 まで正しいことは、電卓を使えば簡単にチェッ クできる。)
まで正しい答えが求まるならば、レポートに付ける実行例は の値が以上の実行 例を付けるのが妥当である。
型の変数を用いた場合、表現できる最大の正の整数は (これも 電卓を使えば簡単に計算できる)であり、これを出力するためには少なくとも桁必要であ る。の値は大きくなることが予想されるので、左側に出力する数値との間の空白と「−」
が付く可能性も考えると、見やすい出力を得るためにの値は少なくとも桁(書式制御 文字として「」)以上で出力する必要がある。
正しい答えを出す最大のに関して、全く触れていないレポートがあった。演習で指示され た事に関する考察をレポートに記載するべきである。
「 や や まで正しい答えが得られる」としたレポートも多かった。
【プログラムの作成方法】
まず計算に必要な変数とその型を決め、プログラム全体の大きな流れを考えてプログラムの 大枠を作成する。例えば、
の値を 型変数に格納し、の値を 型変数に格 納するものとすると、次のようなプログラムが書ける。(これはまだ未完成だが、コンパイ ルして実行することはできる(実行結果は正しくないが‥‥))
!" #や$ #に必要なヘッダファイル
$ %
&
' ( と の値を覚える変数
' !( ) 〜の和 !)
の入力
!" #* *( プロンプトを出力
$ #*+*' , ( の値を入力
#"( ( --& 〜 について以下を繰り返す
を求める
‥‥ 後でプログラムする
! を求める
! ‥‥ 後でプログラムする
行に' ' ! を桁右詰で印刷
!" #*+++. *' ' ' !(
/
"" ( プログラム正常終了
/
フローチャート等の図を用いて考えるのも良い。
次にを求める方法を考える。は〜の和なので、まず としておき、 〜
の順にに を足していけば、が求まる。そこで、 型の変数 を新たに設け、文 を用いてを求めることにする。
!" #や$ #に必要なヘッダファイル
$ %
&
' ( と の値を覚える変数
' !( ) 〜の和 !)
( の計算に使用する
の入力
!" #* *( プロンプトを出力
$ #*+*' , ( の値を入力
#"( ( --& 〜 について以下を繰り返す
を求める
( まずをに初期化
#"( ( --
- ( 〜 の順に を に足す
! を求める
! ‥‥ 後でプログラムする
行に' ' ! を桁右詰で印刷
!" #*+++. *' ' ' !(
/
"" ( プログラム正常終了
/
同様に、は〜の積なので、まず としておき、 〜の順にに をかけ ていけば、が求まる。この計算は、の計算と同様に、文を用いて実現できる。
!" #や$ #に必要なヘッダファイル
$ %
&
' ( と の値を覚える変数
' !( ) 〜の和 !)
( ' !の計算に使用する
の入力
!" #* *( プロンプトを出力
$ #*+*' , ( の値を入力
#"( ( --& 〜 について以下を繰り返す
を求める
( まずをに初期化
#"( ( --
- ( 〜 の順に を に足す
! を求める
! ( まず ! を に初期化する
#"( ( --
! ! 0 ( 〜 の順に を ! にかける
行に' ' ! を桁右詰で印刷
!" #*+++. *' ' ' !(
/
"" ( プログラム正常終了
/
これで、一応プログラム完成・・・だが、との計算で同じような文を用いているの で、これらを一つにまとめてみる。
!" #や$ #に必要なヘッダファイル
$ %
&
' ( と の値を覚える変数
' !( ) 〜の和 !)
( ' !の計算に使用する
の入力
!" #* *( プロンプトを出力
$ #*+*' , ( の値を入力
#"( ( --& 〜 について以下を繰り返す
' ! を求める
( まずをに初期化、
! ( ! を に初期化する
#"( ( --&
- ( 〜 の順に を に足す
! ! 0 ( 〜 の順に を ! にかける
/
行に' ' ! を桁右詰で印刷
!" #*+++. *' ' ' !(
/
"" ( プログラム正常終了
/
今度こそ完成・・・だが、このプログラムはに関する文の中で更に に関する文が使 われており、効率が悪そうである。(このプログラムの時間複雑度は である。)
〜 の計算に回の加算が行われ、 〜 の計算に回の乗算が行われ る。
そこで、の求め方を考え直してみる。
とすると、 が成立する。このことは、
に関する文の中で、にを足しにを掛けることで、各々 と が求まること を意味している。この考え方をコーディングすると以下のプログラムになる。このプログラ ムの時間複雑度は なので、大きいに対しては先ほどのプログラムより大幅に効率が 良い。
!" #や$ #に必要なヘッダファイル
$ %
&
' ( と の値を覚える変数
' !( ) 〜の和 !)
の入力
!" #* *( プロンプトを出力
$ #*+*' , ( の値を入力
( まずをに初期化、
! ( ! を に初期化する
#"( ( --& 〜 について以下を繰り返す
この時点では 12&3/、! 42&3/ である
- ( これで 12 となる
! ! 0 ( これで ! 42 となる
行に' ' ! を桁右詰で印刷
!" #*+++. *' ' ' !(
/
"" ( プログラム正常終了
/
後は、出力の意味を分かりやすくするために、文の前に見出し行を出力する 文を 加えれば完成する(ソースコードは省略)。
以上、プログラム開発の一例を示したが、まず処理の大まかな流れの部分を作成し、徐々に 詳細化を進めていく開発手法は、 (構造化プログラミング)と 呼ばれ、大規模なプログラム開発に欠かすことができない重要な開発手法である。なお、今 回のプログラムでは関数を使わなかったが、より複雑なプログラムでは、関数を用いること でより分かりやすいプログラムを作ることができる。
「演習1」ができなかった人は、この資料をよく読んで、自力でプログラムを完成できるよ うに復習して欲しい。追加レポートを提出する場合は、この資料を見る前には分からなかっ た点やこの資料を見ることによって理解した点などを記述すること。
を求めるのに
を計算しているプログラムがあった。この場合、時間計算複雑度
プログラムのコメントに出てくる は、各々、 を表す。
〜 の計算に回の加算が行われ、 〜 の計算に回の乗算が行われるのみである。
「 設計」、「階層的設計」と呼ばれることもある。
は で上記のプログラムと同じであるが、新しいに対する
の計算に、加算回、
乗算回、除算回が行われるが、上記のプログラムでは加算回で計算出来る。
プログラム開発では、プログラムの効率計算時間を検討し、より良いプログラムを作成す ることが重要である。