探索アルゴリズム

高等学校情報科「情報Ⅰ」教員研修用教材(本編)の「第3章 コンピュータとプログラミング」ではPythonが使われています。文科省のPythonはPythonじゃねぇのような酷評がありました。その後,少しだけ改善されましたが,まだまだのところもあります。

この128ページ以降に,探索アルゴリズムの話があります。

線形(逐次)探索:

線形探索

インデントがスペース5個だったり4個だったりで統一がとれていませんね。PEP 8 で推奨されている演算子のまわりのスペースやコンマの後のスペースもほとんど入っていません。range() の書き方は始値・増分を省略しない方針のようです。

とりあえず PEP 8 に合わせて書き直してみましょう。range() の流儀は悩ましいところですが,ここでは一般的な書き方に直しました。px にしたのは特に意味はありません(Python の標準モジュール bisect に合わせました)。

def linsearch(a, x):
    for i in range(len(a)):
        if a[i] == x:
            print("見つかりました")
            break


a = [61, 15, 82, 77, 21, 32, 53]
x = 82
linsearch(a, x)

ちなみに,for ループは次のようにするほうが Python らしくなります。研修資料ではこれは教えない方針のようです。

def linsearch(a, x):
    for k in a:
        if k == x:
            print("見つかりました")
            break

二分探索:

線形探索

これもまずは上と同じような方針で整形します。

def binsearch(a, x):
    i = 0
    j = len(a) - 1
    while i <= j:
        m = (i + j) // 2
        if a[m] == x:
            print("見つかりました")
            break
        elif a[m] > x:
            j = m - 1
        else:
            i = m + 1

これは,等しいか・大きいか・小さいかを毎回調べていることになり,三分探索のような感じです。以上か・未満かで二分するようにしてみましょう:

def binsearch(a, x):
    i = 0
    j = len(a) - 1
    while i < j:
        m = (i + j) // 2
        if a[m] < x:
            i = m + 1
        else:
            j = m
    if a[i] == x:
        print("見つかりました")

こちらのほうが比較回数が少ないはずです。


Last modified: