Week 5 (2025/5/16)¶
今週の目的
再帰呼び出しを用いてデータを検索する。
今週のキーワード
- 再帰呼び出し
- 継承
今回はアルゴリズムの実装として、データ列から任意のデータを検索するプログラムを実装する。
具体的には、 先頭から順にデータを探す線形探索 と、中央値と比較して探索空間を半分割していく二分探索 を実装する。なお、線形探索はループを用いたものと再帰呼び出しを用いたものを実装し、二分探索は再帰呼び出しを用いたものを実装する。
課題1:先頭からデータを検索する¶
データをリストに格納するadd
メソッドを備えたDB
クラスを定義せよ。
今回作成するDB
クラスの仕様は、以下の通りである。
DBクラス
class DB()
格納したデータを処理(探索・ソート等)するクラス
add(data)
データを格納するメソッド
パラメータ
- data: 格納するデータ(
Stop
インスタンス)
その後、DB
クラスを継承したDBwLinerSearch
クラスを定義し、バス停IDからバス停名を検索するsearch
メソッドを実装せよ。なお、search
メソッドはループを用いた線形探索アルゴリズムで実装すること。
今回作成するDBwLinerSearch
クラスの仕様は、以下の通りである。
DBwLinerSearchクラス
class DBwLinerSearch()
DB
クラスのサブクラス
格納したデータを線形探索するクラス。
search(query)
格納したデータを線形探索するメソッド
パラメータ
- query: 探索対象のバス停のID(文字列)
返り値
- 探索対象のバス停の名前(文字列)
最後に、実装したDBwLinerSearch
クラスのインスタンスを用いて、allkyotobus_stop.dat
のデータからIDがED01_1653とED01_4089、ED01_5000のバス停を検索し、バス停名と実行時間を表示せよ。なお、allkyotobus_stop.dat
をダウンロードすること。
課題2:先頭からデータを検索する(再帰)¶
課題1で作成したDB
クラスを継承したDBwRecursiveSearch
クラスを定義し、再帰呼び出しを用いてsearch
メソッドの線形探索アルゴリズムを実装せよ。具体的には、リストの先頭がクエリと一致しているかどうかを確認し、一致していればバス停名を返し、そうでなければ、2番目以降のデータ列に対して再帰的に検索を行う。
今回作成するDBwRecursiveSearch
クラスの仕様は、以下の通りである。
DBwRecursiveSearchクラス
class DBwRecursiveSearch()
DB
クラスのサブクラス
格納したデータを再帰呼び出しを用いて線形探索するクラス。
search(query)
格納したデータを再帰呼び出しを用いて線形探索するメソッド
パラメータ
- query: 探索対象のバス停のID(文字列)
返り値
- 探索対象のバス停の名前(文字列)
ヒント
再帰呼び出し時に引数に与える値を変更しないと、基底ケースにたどり着かなくなり無限ループになることに留意せよ。今回の場合、リストの先頭がクエリと異なっていれば、次に探す空間はリストの2番目以降のデータである。
最後に、実装したDBwRecursiveSearch
クラスのインスタンスを用いて、allkyotobus_stop.dat
のデータからIDがED01_1653とED01_4089、ED01_5000のバス停を検索し、バス停名と実行時間を表示せよ。
課題3:二分探索でデータを検索する¶
課題1で作成したDB
クラスを継承したDBwBinarySearch
クラスを定義し、再帰呼び出しを用いた二分探索アルゴリズムでsearch
メソッドを実装せよ。なお、バス停データのIDは"ED01_"に後続する数字が昇順でソートされていることとする。また、ファイルから読み込んだ時点ではIDが文字列のため、数字の大小を比較するには、スライスを用いて"ED01_"以降の数字を切り出し、int()
を用いて数値型に変換する必要がある。具体的にはint(list[m].id[5:])
と記述する。
今回作成するDBwBinarySearch
クラスの仕様は、以下の通りである。
DBwBinarySearchクラス
class DBwBinarySearch()
DB
クラスのサブクラス
格納したデータを二分探索するクラス。
search(query)
格納したデータを二分探索するメソッド
パラメータ
- query: 探索対象のバス停のID(文字列)
返り値
- 探索対象のバス停の名前(文字列)
ヒント
クエリがリストの中央の要素より大きければ、次に探す空間はリストの後半のデータ列である。一方、クエリがリストの中央の要素より小さければ、次に探す空間はリストの前半のデータ列である。
最後に、これまで実装したDBwLinerSearch
クラス、DBwRecursiveSearch
クラス、DBwBinarySearch
クラスの各インスタンスを用いて、allkyotobus_stop.dat
のデータからIDがED01_1653とED01_4089、ED01_5000のバス停を検索し、バス停名と実行時間を表示せよ。本課題は、実装が異なると実行速度が変わることを理解することが目的である。
ID:ED01_1653は府立大学前です。DBwLinerSearchは1.0013580322265625e-05秒かかりました。
ID:ED01_4089は京都駅前です。DBwLinerSearchは0.000102996826171875秒かかりました。
ID:ED01_5000はNoneです。DBwLinerSearchは0.0001780986785888672秒かかりました。
ID:ED01_1653は府立大学前です。DBwRecursiveSearchは0.001550912857055664秒かかりました。
ID:ED01_4089は京都駅前です。DBwRecursiveSearchは0.041697025299072266秒かかりました。
ID:ED01_5000はNoneです。DBwRecursiveSearchは0.02522110939025879秒かかりました。
ID:ED01_1653は府立大学前です。DBwBinarySearchは2.5033950805664062e-05秒かかりました。
ID:ED01_4089は京都駅前です。DBwBinarySearchは0.00015163421630859375秒かかりました。
ID:ED01_5000はNoneです。DBwBinarySearchは1.4781951904296875e-05秒かかりました。