間違いあり! 独学コンピューターサイエンティスト 第1部 第4章 p95 の指摘について
以下のツイートは、独学コンピューターサイエンティスト監訳者の清水川貴之さんへ向けてのものです。
ケツカッチンで、急いで斜め読みしてる途中で見つけたものなので、検証してみました。
検証の為に、p87 のマージソートサンプルプログラム の一部を変更しました。指摘した部分の各値とマージソート関数を呼び出す箇所を追加しています。
以下が、その変更を加えたサンプルプログラムと出力結果です。
def merge_sort(a_list):
if len(a_list) > 1:
mid = len(a_list) // 2
left = a_list[:mid] # 修正前: left_half
right = a_list[mid:] # 修正前: right_half
merge_sort(left)
merge_sort(right)
left_i = 0 # 修正前: left_ind
right_i = 0 # 修正前: right_ind
alist_i = 0 # 修正前: alias_ind
while (
left_i < len(left) and
right_i < len(right)
):
if left[left_i] <= right[right_i]:
a_list[alist_i] = left[left_i]
left_i += 1
else:
a_list[alist_i] = right[right_i]
right_i += 1
alist_i += 1
# 検証の為、以下の print文を追加!
print(' while ( left_i < len(left) and right_i < len(right): ループ後の値!')
print(' left_i =', left_i, ' len(left) =', len(left),
' left_i が len(left) より大きくなることはない')
print(' right_i =', right_i, ' len(right) =', len(right),
' right_i が len(right) より大きくなることはない', end='\n\n')
while left_i < len(left):
a_list[alist_i] = left[left_i]
left_i += 1
alist_i += 1
while right_i < len(right):
a_list[alist_i] = right[right_i]
right_i += 1
alist_i += 1
return a_list
# merge_sort関数を実行するために以下を追加!
list = [6, 3, 9, 4, 1, 10, 3] # ソートされるリスト
print('ソート結果!', list, '=>', merge_sort(list[:]))
出力結果
while ( left_i < len(left) and right_i < len(right): ループ後の値!
left_i = 1 len(left) = 1 left_i が len(left) より大きくなることはない
right_i = 0 len(right) = 1 right_i が len(right) より大きくなることはない
while ( left_i < len(left) and right_i < len(right): ループ後の値!
left_i = 1 len(left) = 1 left_i が len(left) より大きくなることはない
right_i = 1 len(right) = 2 right_i が len(right) より大きくなることはない
while ( left_i < len(left) and right_i < len(right): ループ後の値!
left_i = 0 len(left) = 1 left_i が len(left) より大きくなることはない
right_i = 1 len(right) = 1 right_i が len(right) より大きくなることはない
while ( left_i < len(left) and right_i < len(right): ループ後の値!
left_i = 0 len(left) = 1 left_i が len(left) より大きくなることはない
right_i = 1 len(right) = 1 right_i が len(right) より大きくなることはない
while ( left_i < len(left) and right_i < len(right): ループ後の値!
left_i = 2 len(left) = 2 left_i が len(left) より大きくなることはない
right_i = 1 len(right) = 2 right_i が len(right) より大きくなることはない
while ( left_i < len(left) and right_i < len(right): ループ後の値!
left_i = 3 len(left) = 3 left_i が len(left) より大きくなることはない
right_i = 3 len(right) = 4 right_i が len(right) より大きくなることはない
ソート結果! [6, 3, 9, 4, 1, 10, 3] => [1, 3, 3, 4, 6, 9, 10]
出力結果から分かるように、left_i と len(left) が同じか、 もしくは right_i と len(right) が同じ時に、whileループを抜けています。
指摘させてもらった事は間違っていませんでした。
実は、この指摘をさせてもらった後に、このサンプルマージソート関数は、全ての whileループ判定の < を != に置き換えても問題ない気がしたので、全ての < を != を置き換えてみました。
以下が、その < を != 置き換えたプログラムの note 記事です。
後、これは重箱の隅をつつくような事なので報告しませんでしたが、p95 の、
は、
次に、left_i は left の長さより小さいので、
の方が適切でしょう。left_i はインデックスを表す整数なので・・・
𝑷𝑺
2023-01-19 現在、この間違いは正誤表に載っていません。しかし、この間違いの確認をしていただける事が分かりました。
以下は、その確認が取れた清水川貴之さんのツイートです。
[追記]
対応していただきました。
#独学コンピューターサイエンティスト
#独CS #selftaughtcoder
#Python #Python3
#マージソート
#サンプルプログラム
#清水川貴之 さん