アルゴリズムとデータ構
造
2.「制御構造,再帰」
2011 年 4 月 19 日(火)
服部 健太
2011/4/19 アルゴリズムとデータ構造 2 2
概要
 アルゴリズムを記述するために,必要最小限
な Python の構文,意味について説明する
 値と式
 変数
 基本的な制御構造
 手続き(関数)の書き方,使い方
 手続き(関数)の再帰呼び出し
 対話型インタプリタを使って,プログラムの
入力と出力結果を確認しながら進める
2011/4/19 アルゴリズムとデータ構造 2 3
Python で扱える値の種類
 数値
 整数
 -3, 0, 1234, ... など
 浮動少数点数
 1.23, 0.0, -1.11, ... など
 真偽値
 True, または, False
 文字列
 “Hello”, ‘foo’, “X”, “This is a pen.”, ‘My name is “Kenta”’, ...
 シングルクォート,もしくは,ダブルクォートで囲まれた文字
の並び
 None
 None は値が「無い」ことを示す特別な値である
 【確認】
 インタプリタ上から,上記の値をいくつか入力して,応答を確
かめよ
2011/4/19 アルゴリズムとデータ構造 2 4
演算子と式
 算術演算
 +, -, *, /
 % (剰余)
 ** (べき乗)
 比較演算
 <, <=, >, >=
 ==, !=
 論理演算
 and, or, not
 式
 演算子と値を組み合わせる
ことで様々な式を作ること
ができる
 例:
 3 + 5 * 10
 3.14 * 2 > 5
 1 + 1 == 2
 3 > 0 and 3 – 5 < 0
 演算子の結合優先順位を変
えるには,括弧を使う
 (1 + 2) * 3
 【確認】
 いろいろな式を入力してみ
よ
2011/4/19 アルゴリズムとデータ構造 2 5
変数
 変数は値につける名前である.
 値の入れ物とみなすこともできる.
 変数名のルール
 先頭は英文字か下線,その後は英文字,数字,下線のいずれか
 _spam, spam, Spam_1 OK⇒
 1_Spam, spam$, @#1 NG⇒
 大文字と小文字は区別される
 SPAM, spam は同じではない
 予約語は変数名としては使用できない
 and, or, if, in, pass, return, while, not, or, ... など
 変数の作成
 = の左辺に作成した変数を書き,右辺にその変数が指す値を書く
 my_name = “Hattori”, pi = 3.1415, ...
3x: Truey:
2011/4/19 アルゴリズムとデータ構造 2 6
配列
 整数のインデックスで参照される値の並び.
 もっとも基本的なデータ構造の一つ.
 計算機のメモリは大きな 1 次元の配列とみなせる.
 配列の作成
 以下のように各括弧の中に要素となる値をカンマで区切って記述する
 A = [1,2,3,4,5], str_array = [“foo”, “bar”, “baz”], empty_array = []
 サイズだけ指定して配列を確保する場合には,以下のように array 関数を使う
 B = array(10) # 大きさ 10 の配列を作成して変数 B に代入
 配列の参照
 要素への参照は,配列名の後に角かっこで囲まれたインデックスをつけて表す.
 インデックスは 0 始まりであることに注意
 例:
 A[0] --- 配列 A の 1 番目の要素
 A[i] --- 配列 A の i+1 番目の要素
 B[j - 1] --- 配列 B の j 番目の要素
 配列の長さは, len 関数を用いて len(A) のように取得できる
 【注意】
 ここで説明している配列は, Python ではリストと呼ばれるものである.
 array はこの講義用に独自に定義した関数であり,標準の Python には含まれていない
2011/4/19 アルゴリズムとデータ構造 2 7
複合データ(レコード)
 配列のように複数の値からなるデータだが,フィールド名を用
いて要素を参照できる.
 データ名の後に「.フィールド名」を続けることで要素を参照
する
 例:
 S.top, node.head, x.prev.next
 レコードの生成
 以下のように, record({}) ’ ’の中に, フィールド名 : 式を並べる
 r1 = record({‘name’: “Hattori”, ‘age’: 38})
 【注意】
 上記の record 関数は,本講義向けに独自に定義した関数であり
,標準の Python には含まれない.
 Python にはレコードが無いため,クラスを用いて擬似的に実現している.
2011/4/19 アルゴリズムとデータ構造 2 8
タプル(組)
 レコードのように複数のデータをまとめて扱う
 タプルの作成
 以下のように,要素をカンマで区切る(丸括弧はつけなく
てもよい)
 T = (“ISP”, 1977, “Shibuya”)
 タプルからの取り出し
 以下のように, = の左辺に取り出したいデータを格納する
変数を並べる
 x,y,z = 0,True, “foo”
 【参考】
 配列のように角括弧とインデックスを使ってデータを参照
することもできる
2011/4/19 アルゴリズムとデータ構造 2 9
代入文
 変数や配列の要素,複合データの
フィールドに値を入れなおす
 等号を使って「変数名 = 式」のよ
うに書く
 同時代入は「変数名1 = 変数名2 =
式」のように書く
 式を計算した値が新しく変数に入
れられる.
 例:
 x = 3, y = 1, z = x + y,…
 A[i] = B[j]+1, x.key = 0, …
 代入の前後で,変数が持つ値が変わ
る
 【注意】
 変数の作成と同じである
3x:
4x:
4x:
x = x + 1
y = x + 2
1y:
1y:
6y:
計算の進行
2011/4/19 アルゴリズムとデータ構造 2 10
逐次実行文
 1 行ずつ上から順番に計算を実行していく
 例:
t = x # (1)
x = y # (2)
y = t # (3)
 この場合, (1) を実行した後, (2) を実行し,最後に (3) を実行
する
 どうしても1行に書きたい場合は, ; (セミコロン)を使って文
を並べる
 t = x; x = y; y = t
 【問題】上の一連の代入文を実行することで,何が起こるか説
明せよ.
 ブロック文
 一連の逐次実行文の固まりは,インデントで表現する.
t = x
x = y
y = t
2011/4/19 アルゴリズムとデータ構造 2 11
条件分岐文
 ある条件が成立するかどうかで異なる計算を実行する.
 「条件が成立する」とは,条件式を計算した結果が True (真)となることを意
味する.
 以下のように表記する
 if 条件式 :
 文1
 else :
 文2
 条件式を計算した結果が真なら文1を実行し,偽なら文2を実行する.
 if 条件式 :
 文1
 条件式を計算した結果が真なら文1を実行し,偽なら何もしない
 例:
if x < 0:
y = -x
else:
y = x
 問題:上の計算は何を行っているのか説明せよ.また,上のコードを,結果を変えず
に, else 節なしの if 文を用いて書き換えられるか?
文1 文2
条件
文1
条件
真 偽
真
偽
2011/4/19 アルゴリズムとデータ構造 2 12
反復実行文
 同じパターンの計算を繰り返し実行する.
 for 文:一定回数の繰り返し
 for 変数名 in range( 式1 , 式2 ):
 文
 式1を計算した結果を,繰り返しの変数に代入し,その変
数が式2に等しくなるまで文を繰り返す.繰り返しの度に
,変数の値がひとつずつ増えていく.
 繰り返しの変数は,繰り返しを抜けた後でもその値を保持
する
 例:
s = 0
for i in range(1, 11):
s = s + i
 問題 :s と i の値は最終的に何になるか?
文 一定回数
2011/4/19 アルゴリズムとデータ構造 2 13
反復実行文(2)
 条件によって実行を繰り返す
 while 文
 while 条件式 :
 文
 条件式が真の間,文の実行を繰り返す.
 break 文を用いた while ループの脱出
 whle True:
 文
 if not 条件式 : break
 条件式が偽になるまで,文の実行を繰り返す.
 後者では,最低1回は文が実行されるが,前者の場合は文が1
回も実行されない場合がありうる.
文
条件
文
条件
真
偽
真
偽
2011/4/19 アルゴリズムとデータ構造 2 14
手続き(関数)
 一連の計算手順をまとめて,名前をつけたものを手続きと呼ぶ
.
 手続きのうち,値を返すものを関数と呼ぶこともある.
 手続き定義の構文
 def 手続き名 ( …パラメータ名, ):
 本体
 手続きはいくつかの入力パラメータを受け取り,本体を実行す
る.
 手続き(関数)の例:
def sum_of_square(A):
s = 0
for i in A:
s = s + i*i # s += i*i と書いても良い
return s
return 文は値を返し
て,手続き(関
数)の実行を終了
する.
2011/4/19 アルゴリズムとデータ構造 2 15
手続きの呼び出し
 パラメータを与えて手続きを呼び出す.
 手続き名 ( …式1,式2, )
 …式1,式2, をそれぞれ計算し,それらの値を
パラメータとして手続きを呼び出す
 パラメータの数は一致していること.
 例:
 x = sum_of_square([1,2,3,4,5])
2011/4/19 アルゴリズムとデータ構造 2 16
パラメータ渡しについて
 パラメータは値渡しである.
 すなわち,手続き本体でパラメータが変更されても,呼び
出し側の変数には影響を受けない.
 例:以下のような swap 手続きを定義して, swap(x,y) を
呼び出しても, x と y の値は入れ替わらない.
def swap(a,b):
t = a
a = b
b = t
 ただし,複合データ ( 配列やレコード ) の場合,複合デー
タへの参照(ポインタ)が渡されるものとする.
 すなわち, x がパラメータだった場合, x.foo = 3 というよう
な代入は呼び出し側にも影響を与える.
2011/4/19 アルゴリズムとデータ構造 2 17
再帰呼び出し
 自分自身の手続き(関数)を呼び出すこともできる
.
 例:
 N の階乗 N! は,以下のように再帰的に定義される
 Python では,再帰呼び出しを用いて以下のように書くこと
ができる.
def fact(n):
if n == 0: return 1
else: return n * fact(n-1)



>−⋅
=
=
0,)!1(
0,1
!
NNN
N
N
2011/4/19 アルゴリズムとデータ構造 2 18
GCD 再帰呼び出し版
def GCD(p,q):
if q == 0:
return p
else:
return GCD(q, p % q)
 練習問題:
 上記の再帰版 GCD のコードに従っ
て, GCD(54,39) の計算をステップ実行の様子を
示せ.
2011/4/19 アルゴリズムとデータ構造 2 19
練習問題
 さきほどの fact 関数を,再帰呼び出しのかわ
りに while 文を使って書き直せ.
 ヒント:
 N! = N * (N – 1) * ・・・ * 2 * 1
2011/4/19 アルゴリズムとデータ構造 2 20
解答例
def fact_iter(n):
prod = 1
while n > 0:
prod = prod * n
n = n - 1
return prod

アルゴリズムとデータ構造2

  • 1.
  • 2.
    2011/4/19 アルゴリズムとデータ構造 22 概要  アルゴリズムを記述するために,必要最小限 な Python の構文,意味について説明する  値と式  変数  基本的な制御構造  手続き(関数)の書き方,使い方  手続き(関数)の再帰呼び出し  対話型インタプリタを使って,プログラムの 入力と出力結果を確認しながら進める
  • 3.
    2011/4/19 アルゴリズムとデータ構造 23 Python で扱える値の種類  数値  整数  -3, 0, 1234, ... など  浮動少数点数  1.23, 0.0, -1.11, ... など  真偽値  True, または, False  文字列  “Hello”, ‘foo’, “X”, “This is a pen.”, ‘My name is “Kenta”’, ...  シングルクォート,もしくは,ダブルクォートで囲まれた文字 の並び  None  None は値が「無い」ことを示す特別な値である  【確認】  インタプリタ上から,上記の値をいくつか入力して,応答を確 かめよ
  • 4.
    2011/4/19 アルゴリズムとデータ構造 24 演算子と式  算術演算  +, -, *, /  % (剰余)  ** (べき乗)  比較演算  <, <=, >, >=  ==, !=  論理演算  and, or, not  式  演算子と値を組み合わせる ことで様々な式を作ること ができる  例:  3 + 5 * 10  3.14 * 2 > 5  1 + 1 == 2  3 > 0 and 3 – 5 < 0  演算子の結合優先順位を変 えるには,括弧を使う  (1 + 2) * 3  【確認】  いろいろな式を入力してみ よ
  • 5.
    2011/4/19 アルゴリズムとデータ構造 25 変数  変数は値につける名前である.  値の入れ物とみなすこともできる.  変数名のルール  先頭は英文字か下線,その後は英文字,数字,下線のいずれか  _spam, spam, Spam_1 OK⇒  1_Spam, spam$, @#1 NG⇒  大文字と小文字は区別される  SPAM, spam は同じではない  予約語は変数名としては使用できない  and, or, if, in, pass, return, while, not, or, ... など  変数の作成  = の左辺に作成した変数を書き,右辺にその変数が指す値を書く  my_name = “Hattori”, pi = 3.1415, ... 3x: Truey:
  • 6.
    2011/4/19 アルゴリズムとデータ構造 26 配列  整数のインデックスで参照される値の並び.  もっとも基本的なデータ構造の一つ.  計算機のメモリは大きな 1 次元の配列とみなせる.  配列の作成  以下のように各括弧の中に要素となる値をカンマで区切って記述する  A = [1,2,3,4,5], str_array = [“foo”, “bar”, “baz”], empty_array = []  サイズだけ指定して配列を確保する場合には,以下のように array 関数を使う  B = array(10) # 大きさ 10 の配列を作成して変数 B に代入  配列の参照  要素への参照は,配列名の後に角かっこで囲まれたインデックスをつけて表す.  インデックスは 0 始まりであることに注意  例:  A[0] --- 配列 A の 1 番目の要素  A[i] --- 配列 A の i+1 番目の要素  B[j - 1] --- 配列 B の j 番目の要素  配列の長さは, len 関数を用いて len(A) のように取得できる  【注意】  ここで説明している配列は, Python ではリストと呼ばれるものである.  array はこの講義用に独自に定義した関数であり,標準の Python には含まれていない
  • 7.
    2011/4/19 アルゴリズムとデータ構造 27 複合データ(レコード)  配列のように複数の値からなるデータだが,フィールド名を用 いて要素を参照できる.  データ名の後に「.フィールド名」を続けることで要素を参照 する  例:  S.top, node.head, x.prev.next  レコードの生成  以下のように, record({}) ’ ’の中に, フィールド名 : 式を並べる  r1 = record({‘name’: “Hattori”, ‘age’: 38})  【注意】  上記の record 関数は,本講義向けに独自に定義した関数であり ,標準の Python には含まれない.  Python にはレコードが無いため,クラスを用いて擬似的に実現している.
  • 8.
    2011/4/19 アルゴリズムとデータ構造 28 タプル(組)  レコードのように複数のデータをまとめて扱う  タプルの作成  以下のように,要素をカンマで区切る(丸括弧はつけなく てもよい)  T = (“ISP”, 1977, “Shibuya”)  タプルからの取り出し  以下のように, = の左辺に取り出したいデータを格納する 変数を並べる  x,y,z = 0,True, “foo”  【参考】  配列のように角括弧とインデックスを使ってデータを参照 することもできる
  • 9.
    2011/4/19 アルゴリズムとデータ構造 29 代入文  変数や配列の要素,複合データの フィールドに値を入れなおす  等号を使って「変数名 = 式」のよ うに書く  同時代入は「変数名1 = 変数名2 = 式」のように書く  式を計算した値が新しく変数に入 れられる.  例:  x = 3, y = 1, z = x + y,…  A[i] = B[j]+1, x.key = 0, …  代入の前後で,変数が持つ値が変わ る  【注意】  変数の作成と同じである 3x: 4x: 4x: x = x + 1 y = x + 2 1y: 1y: 6y: 計算の進行
  • 10.
    2011/4/19 アルゴリズムとデータ構造 210 逐次実行文  1 行ずつ上から順番に計算を実行していく  例: t = x # (1) x = y # (2) y = t # (3)  この場合, (1) を実行した後, (2) を実行し,最後に (3) を実行 する  どうしても1行に書きたい場合は, ; (セミコロン)を使って文 を並べる  t = x; x = y; y = t  【問題】上の一連の代入文を実行することで,何が起こるか説 明せよ.  ブロック文  一連の逐次実行文の固まりは,インデントで表現する. t = x x = y y = t
  • 11.
    2011/4/19 アルゴリズムとデータ構造 211 条件分岐文  ある条件が成立するかどうかで異なる計算を実行する.  「条件が成立する」とは,条件式を計算した結果が True (真)となることを意 味する.  以下のように表記する  if 条件式 :  文1  else :  文2  条件式を計算した結果が真なら文1を実行し,偽なら文2を実行する.  if 条件式 :  文1  条件式を計算した結果が真なら文1を実行し,偽なら何もしない  例: if x < 0: y = -x else: y = x  問題:上の計算は何を行っているのか説明せよ.また,上のコードを,結果を変えず に, else 節なしの if 文を用いて書き換えられるか? 文1 文2 条件 文1 条件 真 偽 真 偽
  • 12.
    2011/4/19 アルゴリズムとデータ構造 212 反復実行文  同じパターンの計算を繰り返し実行する.  for 文:一定回数の繰り返し  for 変数名 in range( 式1 , 式2 ):  文  式1を計算した結果を,繰り返しの変数に代入し,その変 数が式2に等しくなるまで文を繰り返す.繰り返しの度に ,変数の値がひとつずつ増えていく.  繰り返しの変数は,繰り返しを抜けた後でもその値を保持 する  例: s = 0 for i in range(1, 11): s = s + i  問題 :s と i の値は最終的に何になるか? 文 一定回数
  • 13.
    2011/4/19 アルゴリズムとデータ構造 213 反復実行文(2)  条件によって実行を繰り返す  while 文  while 条件式 :  文  条件式が真の間,文の実行を繰り返す.  break 文を用いた while ループの脱出  whle True:  文  if not 条件式 : break  条件式が偽になるまで,文の実行を繰り返す.  後者では,最低1回は文が実行されるが,前者の場合は文が1 回も実行されない場合がありうる. 文 条件 文 条件 真 偽 真 偽
  • 14.
    2011/4/19 アルゴリズムとデータ構造 214 手続き(関数)  一連の計算手順をまとめて,名前をつけたものを手続きと呼ぶ .  手続きのうち,値を返すものを関数と呼ぶこともある.  手続き定義の構文  def 手続き名 ( …パラメータ名, ):  本体  手続きはいくつかの入力パラメータを受け取り,本体を実行す る.  手続き(関数)の例: def sum_of_square(A): s = 0 for i in A: s = s + i*i # s += i*i と書いても良い return s return 文は値を返し て,手続き(関 数)の実行を終了 する.
  • 15.
    2011/4/19 アルゴリズムとデータ構造 215 手続きの呼び出し  パラメータを与えて手続きを呼び出す.  手続き名 ( …式1,式2, )  …式1,式2, をそれぞれ計算し,それらの値を パラメータとして手続きを呼び出す  パラメータの数は一致していること.  例:  x = sum_of_square([1,2,3,4,5])
  • 16.
    2011/4/19 アルゴリズムとデータ構造 216 パラメータ渡しについて  パラメータは値渡しである.  すなわち,手続き本体でパラメータが変更されても,呼び 出し側の変数には影響を受けない.  例:以下のような swap 手続きを定義して, swap(x,y) を 呼び出しても, x と y の値は入れ替わらない. def swap(a,b): t = a a = b b = t  ただし,複合データ ( 配列やレコード ) の場合,複合デー タへの参照(ポインタ)が渡されるものとする.  すなわち, x がパラメータだった場合, x.foo = 3 というよう な代入は呼び出し側にも影響を与える.
  • 17.
    2011/4/19 アルゴリズムとデータ構造 217 再帰呼び出し  自分自身の手続き(関数)を呼び出すこともできる .  例:  N の階乗 N! は,以下のように再帰的に定義される  Python では,再帰呼び出しを用いて以下のように書くこと ができる. def fact(n): if n == 0: return 1 else: return n * fact(n-1)    >−⋅ = = 0,)!1( 0,1 ! NNN N N
  • 18.
    2011/4/19 アルゴリズムとデータ構造 218 GCD 再帰呼び出し版 def GCD(p,q): if q == 0: return p else: return GCD(q, p % q)  練習問題:  上記の再帰版 GCD のコードに従っ て, GCD(54,39) の計算をステップ実行の様子を 示せ.
  • 19.
    2011/4/19 アルゴリズムとデータ構造 219 練習問題  さきほどの fact 関数を,再帰呼び出しのかわ りに while 文を使って書き直せ.  ヒント:  N! = N * (N – 1) * ・・・ * 2 * 1
  • 20.
    2011/4/19 アルゴリズムとデータ構造 220 解答例 def fact_iter(n): prod = 1 while n > 0: prod = prod * n n = n - 1 return prod