pe-5. 繰り返し計算
1
(Pascal プログラミング入門)
URL: https://www.kkaneko.jp/pro/pascal/index.html
金子邦彦
while文とfor文による繰り返し計算の実装、ループカウンタ
の使用と字下げによる可読性の高いプログラム作成
【学習内容の構成】
1. while文:条件が真である限り処理を繰り返す制御構造
2. for文と繰り返しの入れ子:指定回数の繰り返しと二重ル
ープによる表形式出力
3. 計算誤差の累積:繰り返し計算における近似計算と誤差
の蓄積
• 前提:Pascalの基本文法、変数と代入、条件式の理解
• 意義:自然数の和、最大公約数、九九の表など実用的なア
ルゴリズムの実装能力の習得
2
繰り返しとは
• 繰り返しとは,ある条件が満たされるまで,同じ
ことを繰り返すこと.
• 繰り返しを行うための文としてwhile文, for 文な
どがある.
3
条件
繰り返しの例
• ユークリッドの互除法
• m と n の最大公約数を求めるために,「割った余りを
求めること」を,余りが0になるまで繰り返す.
• 九九の表
• 九九の表を求めるために,掛け算を81回繰り返す
4
オンライン開発環境 Online GDB
• プログラミングを行えるオンラインのサービス
https://www.onlinegdb.com
• ウェブブラウザを使う
• たくさんの言語を扱うことができる
Pascal, Python3, Java, C/C++, C#, JavaScript,
R, アセンブリ言語,SQL など
• オンラインなので、「秘密にしたいプログラム」
を扱うには十分な注意が必要
5
Online GDB で Pascal を動かす手順
① ウェブブラウザを起動する
② 次の URL を開く
https://www.onlinegdb.com
6
③ 「Language」のところで,「Pascal」を選ぶ
7
エディタ画面
実行ボタン
プログラムを
書き換えること
ができる
8
例題1.自然数の和
• 整数データ(Nとする)を読み込んで,1からN
までの和を求めるプログラムを作る
• ここでは,練習のため,自然数の和の公式は使わ
ずに,while文を用いる
例) 100 → 5050
9
program sum;
var N, i, s: integer;
begin
write('sum [1..N] Program. Please Enter N: ');
readln(N);
s := 0;
i := 1;
while i <= n do begin
s := s + i;
i := i + 1;
end;
writeln('sum[1..n] = ', s:8);
readln
end.
10
繰り返し実行される
部分
条件式
自然数の和
11
実行結果の例
プログラム実行順
12
s := 0;
i := 1;
i <= N
s := s + i;
i := i + 1;
Yes
No
繰り返し処理の中身
• 繰り返しの前
i := 1 と S := 0 を実行
• 繰り返しの各ステップでなされること
1. 「S」 に 「i」 を足しこむ
→ 「S」には,その時点での「1から i 」までの和
が入る
2. 「i」 の値を1増やす
• 繰り返しの終了条件
i <= N が成り立たなくなったら終了
→ つまり i > N になったら終了
13
自然数の和
14
N = 7 とすると
i <= 7 が成立する
s = 0 + 1
i <= 7 が成立する
s = 1 + 2
i <= 7 が成立する
s = 3 + 3
i <= 7 が成立する
s = 6 + 4
i <= 7 が成立する
s = 10 + 5
i <= 7 が成立する
s = 15 + 6
i <= 7 が成立する
s = 21 + 7
i <= 7 が成立しない
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
繰り返し
1回目
繰り返し
2回目
繰り返し
3回目
繰り返し
4回目
繰り返し
5回目
繰り返し
6回目
繰り返し
7回目
繰り返し
8回目
s の値
i の値
はじめは s = 0 i = 1
while 文
• 何かの処理の繰り返し
• 繰り返しのたびに while 文で書かれた条件式の真
偽が判定され, 真である限り,while のあとに続
く文が実行され続ける.
15
while 条件式 do begin
式1;
式2;
...
end
条件式
式1
式2
...
Yes
No
例題2.最大公約数の計算
• 2つの整数データを読み込んで,最大公約数を求
めるプログラムを作る.
• ユークリッドの互除法を用いること
• ユークリッドの互除法を行うために while 文を書く
例) 20, 12 のとき: 4
16
ユークリッドの互除法
• 最大公約数を求めるための手続き
• m,nの最大公約数は,
• m ≧ n とすると,
• 「m をn で割った余り」 = 0 なら,最大公約数は n
• 「m をn で割った余り」 > 0 なら,m と n の最大公約
数は, 「m をn で割った余り」 と n の最大公約数に等
しい
( なお,n > 「m をn で割った余り」 が成り立つ)
17
program sum;
var r, m, n: integer;
begin
write('GCD Program. Please Enter m: ');
readln(m);
write('Please Enter n: ');
readln(n);
r := m mod n;
while r > 0 do begin
m := n;
n := r;
r := m mod n;
end;
writeln('GCD = ', n:8);
readln
end.
18
条件が成り立つ限り,
実行されつづける部分
条件式
最大公約数の計算
19
実行結果の例
プログラム実行順
20
r := m % n;
r > 0
m := n;
n := r;
r := m mod n;
Yes
No
繰り返し処理の中身
• 繰り返しの前
r := m mod n を実行(m を n で割った余りが r に入る)
• 繰り返しの各ステップでなされること
m := n;
n := r;
r := m mod n;
を実行(m, n, r の値は小さくなっていく)
• 繰り返しの終了条件
r が 0 になったら終了
21
最大公約数の計算
22
m = 80, n = 35 とすると,
最初の「 r = m mod n; 」で, r = 10 になる
r > 0 が成立する
m = 35 n = 10 r = 5
r > 0 が成立する
m = 10 n = 5 r = 0
r > 0 が成立しない
繰り返し
1回目
繰り返し
2回目
繰り返し
3回目
m の値
n の値
r の値
80, 35 の最大公約数は
35, 10 の最大公約数に等しい
35, 10 の最大公約数は
10, 5 の最大公約数に等しい
例題3.総和と平均
• データ x1, x2, ... xk を1つづつ読み込んで,合計
と平均を求めるプログラムを作成す
• 負の数が入力されたら終了する
整数のデータ 1, 2, 3 に対して
1
2
3
-1
23
入力
program sum;
var x, s: real;
var i: integer;
begin
s := 0;
i := 0;
write('Please Enter x[', i:3, ']: ');
readln(x);
while 0 <= x do begin
s := s + x;
i := i + 1;
write('Please Enter x[', i:3, ']: ');
readln(x);
end;
writeln('sum =', s:8:3);
writeln('average =', (s/i):8:3);
readln
end.
24
条件が成り立つ限り,
実行されつづける部分
条件式
総和と平均
25
実行結果の例
プログラム実行順
26
s := 0;
i := 0;
write('Please Enter x[', i:3, ']: ');
readln(x);
0 <= x
s := s + x;
i := i + 1;
write('Please Enter x[', i:3, ']: ');
readln(x);
Yes
No
繰り返し処理の中身
• 繰り返しの前
S := 0 と i := 0 を実行
X0 を読み込む
• 繰り返しの各ステップでなされること
1. 「S」 に 「Xi」 を足しこむ
→ 「S」には,その時点での「X0から Xi 」までの和
が入る
2. 「i」 の値を1増やす
3. Xi を読み込む
• 繰り返しの終了条件
Xi < 0 ならば終了
27
演習1.m から n までの和
• 2つの整数データ(M, Nとする)を読み込んで,
MからNまでの和を求めるプログラムを作りなさい
• while 文を使いなさい.例題1のプログラムを参考にし
なさい
28
例題4.九九の表
• 九九の表を表示するプログラムを作成する
• 九九の表を表示するために,繰り返しの入れ子を使う
29
program sum;
uses SysUtils;
var i, j: integer;
begin
for i := 1 to 9 do begin
write( i:3, ':' );
for j := 1 to 9 do begin
write( (i*j):3 );
end;
writeln;
end;
readln
end.
30
繰り返し実行される部分
実行結果画面(例)
31
繰り返しの入れ子
32
九九の表
33
i := 1
i <= 9
Yes
No
j := 1
j <= 9
Yes
九九の表を表示
j := j + 1;
No
i := i + 1;
for 文
34
for 変数名 := 初期値 to 終了値 do begin
式1;
式2;
...
end
例題5.ド・モアブルの定理
• θを読み込んで,次の値を計算するプログラムを作
る
• なお,i は虚数単位
• ここでは (sinθ+ i cosθ)n を求めるために,while文を用
いた繰り返し計算を行ってみる
35
( )
n
i
sincos +
nin sincos +
複素数の積
z1 = x1 + i y1
z2 = x2 + i y2 のとき
z1 z2 = (x1 + i y1) (x2 + i y2 )
= x1x2 + x1i y2 + i y1x2 + i y1i y2
= x1x2 - y1y2 + i (x1y2 + y1x2 )
36
実数部
虚数部
program sum;
var j, n: integer;
var x1, y1, x2, y2, theta: real;
begin
write('Please Enter n: ');
readln(n);
write('Please Enter theta: ');
readln(theta);
x1 := cos(theta);
y1 := sin(theta);
x2 := x1;
y2 := y1;
j := 1;
while j <= n do begin
writeln( '(cos theta + i sin theta)', j, '=', x1:8:3, '+ i ', y1:8:3 );
writeln( 'cos', j, 'theta + i sin', j, 'theta =', cos( j * theta ):8:3, sin( j * theta ):8:3 );
x1 := x1 * x2 - y1 * y2;
y1 := x1 * y2 + x2 * y1;
j := j + 1;
end;
readln
end.
37
繰り返し実行される
部分
条件式
実行結果画面(例)
38
繰り返し処理の中身
• 繰り返しの前
x1 := cos θ
y1 := sin θ
x2 := x1
y2 := y1
を実行
• 繰り返しの各ステップでなされること
x1 := x1 * x2 - y1 * y2
y1 := x1 * y2 + x2 * y1;
を実行 (x1 が実数部,y1 が虚数部)
39
(cosθ+ i sinθ)n = cos nθ+ i sin nθ
(cosθ+ i sinθ)2 = cos2θ- sin2θ+ 2i cosθsin θ
= cos2θ+ i sin2θ
(cosθ+ i sinθ)3 = (cosθ+ i sinθ)2 (cosθ+ i sinθ)
= (cos2θ+i sin2θ) (cosθ+ i sinθ)
= cos2θcosθ- sin2θsinθ
+ i (cos2θsinθ- sin2θcosθ)
= cos (2θ+θ) + i sin (2θ+θ)
= cos3θ+ i sin3θ
(以下同様に考える.数学的帰納法で証明できる)
40
計算結果から分かること
• 本来なら「 (cosθ+ i sinθ)n = cos nθ+ i sin nθ 」が
成り立つはず
• しかし,コンピュータでの計算は,近似計算
• 計算を繰り返す(つまり、計算結果を使った計算)
たびに,誤差が積み重なる
41