今天写了波python,感觉好久没写有点生疏了,今天就学点新东西,练练手感。选了个哈希表(要不是C没有内置哈希,我说不定又拖延了)
那就开始吧,首先介绍一下哈希算法,这个算法可以把输入的数字转换为固定长度的哈希值,即使是非常小的差距,最终生成的哈希值差距也会很大(虽然怎么定义哈希值相似程度还不是我这个萌新该考虑的)。所以哈希算法一般用于密码学、数据完整性校验、数据索引等领域。
哈希查找
python中应该是有内置哈希表的,我们直接调用
#初始化哈希表
hmap :dict = {}
#添加键值对
hmap[12836] = "Hokma"
hmap[10086] = "Rouland"
hmap[12306] = "Mallkuth"
'''省略,你想添加啥再添加吧,我饿了'''
#查询操作
#因为还记得吗,数值最后生成的哈希值相差很大,所以用这个来查询
name: str = hmap[10086] #str是哈希表里存的数据类型,说不定这里的str可以换成其他类型的,不过一般
#一个哈希表里面只存一种类型的值吧
哈希表的遍历有三种方法,应该都知道什么是遍历吧
#遍历的三种方法
#遍历键值对
for key, value in hmap.items():
print(key, "->", value)
#单独遍历key
for key in hmap.keys():
print(key)
#单独遍历value #ps:之前玩没有中文的游戏时,总是出现value这个单词,一直不知道
for value in hmap.values(): #什么意思,现在知道了,这是值的意思,虽然跟价值差不多
print(value)
注意到了吗?hmap.后面接的东西就对应这你要遍历的东西,如果知道一点python的语法结构,应该就能很快明白。
我之前一直觉得查找是一个比较复杂的东西,就像搜索引擎,不过哈希查找就像数组,只要知道对应的哈希值就能找到你存在这个位置的东西
你输入key,经过哈希算法,得到哈希值,然后你就可以按图索骥(虽然这是贬义词但是我语文不好略略路)
下面是基于数组实现的简单哈希表
class Pair:
"""键值对"""
def __init__(self, key: int, val: str):
self.key = key
self.val = val
class ArrayHashMap:
"""基于数组简易实现的哈希表"""
def __init__(self):
"""构造方法"""
# 初始化数组,包含 100 个桶
self.buckets: list[Pair | None] = [None] * 100
def hash_func(self, key: int) -> int:
"""哈希函数"""
index = key % 100
return index
def get(self, key: int) -> str:
"""查询操作"""
index: int = self.hash_func(key)
pair: Pair = self.buckets[index]
if pair is None:
return None
return pair.val
def put(self, key: int, val: str):
"""添加操作"""
pair = Pair(key, val)
index: int = self.hash_func(key)
self.buckets[index] = pair
def remove(self, key: int):
"""删除操作"""
index: int = self.hash_func(key)
# 置为 None ,代表删除
self.buckets[index] = None
def entry_set(self) -> list[Pair]:
"""获取所有键值对"""
result: list[Pair] = []
for pair in self.buckets:
if pair is not None:
result.append(pair)
return result
def key_set(self) -> list[int]:
"""获取所有键"""
result = []
for pair in self.buckets:
if pair is not None:
result.append(pair.key)
return result
def value_set(self) -> list[str]:
"""获取所有值"""
result = []
for pair in self.buckets:
if pair is not None:
result.append(pair.val)
return result
def print(self):
"""打印哈希表"""
for pair in self.buckets:
if pair is not None:
print(pair.key, "->", pair.val)
(我太懒了,写博客太累了,我就直接CTRL+C了,代码来源hello算法)
不过作为初学者,我就讲讲这其中的一些对于新手不太了解的代码(我只是个老萌新)
class 类,类这个东西就像垃圾分类,其实我感觉有点像C语言中的头文件,你自己编的一个头文件
self 这个是个约定俗称的参数名,因为python中有很多的函数运用都要有对象(可能是叫这个),比如最简单的turtle,如果不用from turtle import *,你后面对turtle的操作都要带turtle.
这是简单的使用self的代码(一般听不懂的看看代码就懂了)
class MyClass:
def __init__(self, name):
self.name = name
def greet(self):
print("Hello, " + self.name)
obj = MyClass("John")
obj.greet() # 输出:Hello, John
但是吧,你想,要是真的真的出现了你输入两个不同的key,但是哈希算法过后得到了一个值,怎么办(一般你升级一波算法就行了,保证绝对不会。但是万一呢万一,又不是万能的)
这个时候就要扩容,概率嘛。(但是扩容是很不方便的操作,所以后面讲怎么跑(就像不管有没有bug,能跑就行))
有一个定义是否需要扩容的东西叫负载因子,意为你存进去的元素个数除以哈希表最多装的元素个数,一般这个值到了0.75你就要扩容了
后面内容等更新吧,这真的累。