探索のプログラムで、データにない値入力への対応

探索のプログラムについては、既に学習したと思います。

今、例として、次のデータから探索し、外部からの入力値(整数を想定) が、item_in という変数に入ってくるものとします。

DNCL データと入力値の変数
Data=[12,21,26,35,44,50,62,75,83,90]
item_in = 整数値(【外部からの入力】)

線形探索で、データにない値入力への対応

まずは線形探索のほうから。
線形探索とは、初めから順番に、等しい値かどうか調べていく、最も単純な方法です。

DNCL 線形探索
i0から 要素数(Data)-1まで1ずつ増やしながら繰り返す:
もし Data[i]==item_in ならば:
表示する("[線形探索]: 入力値",item_in,"は添字",i,"番目に見つかった")
ループを抜ける

これを実行し、入力値として90を入れると、次のようになります。

== 実行結果 ==
?90
[線形探索]: 入力値90は添字 9 番目に見つかった

では、もし入力値を、データにない(データ外の) 値 にしたら、どうなるでしょう\(\dotsm\) 。

== 実行結果 ==
?89
 

\(\dotsm\) 何も表示されません。
データ外の値を入れたとき「見つかりませんでした」と答えさせるには、どうすれば良いでしょう。

DNCL データ外に対応のため最後に挿入
i0から 要素数(Data)-1まで1ずつ増やしながら繰り返す:
もし Data[i]==item_in ならば:
表示する("[線形探索]: 入力値",item_in,"は添字",i,"番目に見つかった")
ループを抜ける
表示する("[線形探索]: 入力値",item_in,"は見つかりませんでした")

ループから出た、最後の行のところに、
いわばこれを入れました。

表示する(“見つかりませんでした”)

それで実行してみると

== 実行結果 ==
?89
[線形探索]: 入力値89は見つかりませんでした 

うまくいきそうですが、データに ある ような値を入力しても同じように

== 実行結果 ==
?90
[線形探索]: 入力値90は添字 9 番目に見つかった
[線形探索]: 入力値90は見つかりませんでした 

\(\dotsm \)「見つかりませんでした」が出てしまいます。
どのようにすればよいでしょうか?。

解決策は、最初の(3)行目のように、初期に真理値を1つおくことです。

DNCL データ外でも機能する線形探索
mitskatta= #真理値を1つ初期設定
i0から 要素数(Data)-1まで1ずつ増やしながら繰り返す:
もし Data[i]==item_in ならば:
表示する("[線形探索]: 入力値",item_in,"は添字",i,"番目に見つかった")
mitskatta=
ループを抜ける
もし not mitskatta ならば:
表示する("[線形探索]: 入力値",item_in,"は見つかりませんでした")
mitskatta= 偽 #真理値を1つ初期設定

真理値は「フラグ」とも呼ばれるものです。
初期設定。ループに入る前に定義しておくことで、ループを回した結果、本当に見つかったかどうか、明示することができるようになります。
これを実行させてみると、

== 実行結果 ==
?90
[線形探索]: 入力値90は添字 9 番目に見つかった
?89
[線形探索]: 入力値89は見つかりませんでした 

「見つかりませんでした」の表示は、データ内(データにある )値では「見つかる」ので、条件分岐で
表示しないようにし、本当に見つからなかったときだけ 出てくるように、うまくできました。

二分探索とは何だったか 復習から

次は、二分探索です。少し大がかりです。
まずは繰り返し利用できる関数を定義しましょう。

DNCL 一回分の二分探索
関数定義 一回分の探索結果(l, r, test_item):
m = 整数値( (l+r)/2 )
もし test_item == Data[m] ならば:
戻り値 (, m, m)
もし test_item < Data[m] ならば:
戻り値 (, l, m-1)
そうでなければ: #test_item > Data[m] のとき
戻り値 (, m+1, r)

ただしデータは、関数の中から閲覧できます。
データから、再掲しておきましょう。はじめ2行にデータが書いてあります。

DNCL 一回分の二分探索まで
Data=[12,21,26,35,44,50,62,75,83,90]
item_in = 整数値(【外部からの入力】)
関数定義 一回分の探索結果(l, r, test_item):
m = 整数値( (l+r)/2 )
もし test_item == Data[m] ならば:
戻り値 (, m, m)
もし test_item < Data[m] ならば:
戻り値 (, l, m-1)
そうでなければ: #test_item > Data[m] のとき
戻り値 (, m+1, r)

その続き。この関数を繰り返し利用することで、絞り込み探索を行ないます。

DNCL 一回分の二分探索を使用する
l, r = 0, 要素数(Data)-1
kaisu = 1
ずっと繰り返す:
#戻り値は一つの配列に詰めて返ってくる:
res_Hi = 一回分の探索結果(l, r, item_in)
is_centerleft = res_Hi[0]
l, r = res_Hi[1], res_Hi[2]
もし is_centerleft ならば: # l=r=m
表示する("[二分探索]: 入力値",item_in,"は添字",l,"番目に見つかった")
ループを抜ける
もし l > r ならば: #データにない値を探させるとなる。
表示する("[二分探索]: 入力値",item_in,"は見つかりませんでした")
ループを抜ける
表示する("[二分ログ]: ",kaisu,"回目。入力値のありかは",l,"番目から",r,"番目に絞れる")
kaisu=kaisu+1

これで実行させてみましょう。

二分探索で、データにない値入力への対応は

再掲しておきます。この部分は変える必要はありません。

DNCL 一回分の二分探索まで
Data=[12,21,26,35,44,50,62,75,83,90]
item_in = 整数値(【外部からの入力】)
関数定義 一回分の探索結果(l, r, test_item):
m = 整数値( (l+r)/2 )
もし test_item == Data[m] ならば:
戻り値 (, m, m)
もし test_item < Data[m] ならば:
戻り値 (, l, m-1)
そうでなければ: #test_item > Data[m] のとき
戻り値 (, m+1, r)

問題はこの後です。

DNCL 一回分の二分探索を使用する
l, r = 0, 要素数(Data)-1
kaisu = 1
ずっと繰り返す:
#戻り値は一つの配列に詰めて返ってくる:
res_Hi = 一回分の探索結果(l, r, item_in)
is_centerleft = res_Hi[0]
l, r = res_Hi[1], res_Hi[2]
もし is_centerleft ならば: # l=r=m
表示する("[二分探索]: 入力値",item_in,"は添字",l,"番目に見つかった")
ループを抜ける
もし l > r ならば: #データにない値を探させるとなる。
表示する("[二分探索]: 入力値",item_in,"は見つかりませんでした")
ループを抜ける
表示する("[二分ログ]: ",kaisu,"回目。入力値のありかは",l,"番目から",r,"番目に絞れる")
kaisu=kaisu+1

これで実行させると、

最初のコメントをしよう

必須
SNSへの投稿はこちら