こんばんは。
いつも応援有難う御座います。m(_ _)m
前回の続きです。
サラっと書いておいた
dump について補足します。
def dump(self):
# i は table[*] のポインタなので table[i]
for i in range(self.capacity):
# table[i] に格納されている key,value,np を呼び出す
p = self.table[i]
# end=""は、次の print と繋げる記述
print(i,end="")
while p is not None:
#前述 i のすぐ後に以下の記述を表示
# p.key , p.value を続けて表示
print(f"=>{p.key}({p.value})",end="")
# p に np を代入して次の key,value,np に繋げる
p = p.np
#改行
print()
前回書いた数珠つなぎでデータを格納するイメージがあれば
何となくイメージしやすいと思います。
今まで、Hash chain を使って、
データを格納してきました。
格納したのだから、その中からデータを探すアプローチにもチャレンジしましょう。
基本的には既に格納されている Node の中の key に紐づけてデータを探します。
def search(self,key):
# key から table のポインタを割り出します。
Vhash = key % self.capacity
p = self.table[Vhash]
while p is not None:
# 格納された key と入力 key が一致した場合。。
if p.key == key:
# データを print で表示
return print(f"searched value is {p.value}")
p = p.np
# while で最後まで該当データを探しても何もない場合、faile
print("faile to search")
用意した配列に追加して、探したのであれば、
不要項目を削除することも出来ますよね?
チャレンジしてみましょう。
search と同じで、基本的には key で該当 Node を見つけます。
そのあとに、Node から Node の接続点を変えれば削除完了です。
そう、Node 中にある np を編集していきます。
def remove(self,key):
Vhash = key % self.capacity
p = self.table[Vhash]
pp = None # 初期値 None
while p is not None:
if p.key == key
#最初のデータを削除する場合の記述
if pp is None:
self.table[Vhash] = self.table[Vhash].np
#最初の項目以外の接続点 np を編集
else:
# pp は後述するがイメージはkey が該当する前の Node
# p は key が該当した Node。
# pp.np に key が該当した Node の np を代入することで
# データの繋ぎから key 該当 Node を削除
pp.np = p.np
# 冒頭の if p.key != key だった場合に pp には p を代入してバッファ
pp = p
# while で先端 Node まで進むために p の値を p.np で更新
p = p.np
Hash とは何ぞや?? っという説明をちゃんとしていませんでした。
私の理解では、key を設けることで、該当する配列のポインタを一発で
見つけることができ、そのあとは、線形探索で該当値を探すことができる
面白い探索方法でした。
上記を実現するために勿論、その規則に沿って格納しなければならないです。
今までの記事は与えられた配列を整頓したり、そのままの並びから
探索するアプローチが基本でした。
今回はそうではなく、格納方法そのものを見直して
探索しやすくしている興味深いアルゴリズムでした。( `ー´)ノ
全体像を載せておきます。
最適案があったり、
問題があれば御教示よろしくお願い致しますm(_ _)m。
class Node:
def __init__(self,key,value,np):
self.key = key
self.value = value
self.np = np
class ChainedHash:
def __init__(self,capacity):
self.capacity = capacity
self.table = [None]*self.capacity
def add(self,key,value):
Vhash = key % self.capacity
p = self.table[Vhash]
while p is not None:
if p.key == key:
return False
p = p.np
temp = Node(key,value,self.table[Vhash])
self.table[Vhash] = temp
def dump(self):
for i in range(self.capacity):
p = self.table[i]
print(i,end="")
while p is not None:
print(f"=>{p.key}({p.value})",end="")
p = p.np
print()
def search(self,key):
Vhash = key % self.capacity
p = self.table[Vhash]
while p is not None:
if p.key == key:
return print(f"searched value is {p.value}")
p = p.np
print("faile to search")
def remove(self,key):
Vhash = key % self.capacity
p = self.table[Vhash]
pp = None
while p is not None:
if p.key == key:
if pp is None:
self.table[Vhash] = self.table[Vhash].np
else:
pp.np = p.np
pp = p
p = p.np
test = ChainedHash(7)
while True:
num = int(input("select 1.add, 2.dump, 3.search, 4.remove : "))
if num == 1:
key = int(input("key: "))
val = int(input("val: "))
test.add(key,val)
elif num == 2:
test.dump()
elif num == 3:
key = int(input("key: "))
test.search(key)
elif num == 4:
key = int(input("key: "))
test.remove(key)
else:
break