zoukankan      html  css  js  c++  java
  • 09-01字典的实现方式

    字典的实现方式

    拉链法

    i = hash(key) % solt
    假设槽位有32个, 那么得到的值很有可能会有冲突, i为最后的该值处于哪个槽位。

    将每个槽位做一个列表, 存值的时候append, 取值的时候遍历。
    如果算法足够好的话, 就几乎能实现近似O(1)了

    实现:
        In [58]: solts = []
            ...: solts_num = 32
            ...: 
            ...: for _ in range(solts_num):
            ...:     solts.append([])
            ...: def put(solts, key, value):
            ...:     i = hash(key) % solts_num
            ...:     solts[i].append((key, value))
            ...: def get(solts, key):
            ...:     i = hash(key) % solts_num
            ...:     for k, v in solts[i]:
            ...:         if k == key:
            ...:             return v
            ...:     raise KeyError(k)
            ...: 
    
        In [59]: put(solts, 'r', 2)
    
        In [60]: solts
        Out[60]: 
        [[],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [('r', 2)],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         [],
         []]
    
        In [66]: put(solts, 'd', 2)
    
        In [67]: get(solts, 'd')
        Out[67]: 2
    版本2:实现插入重复key的处理方式
        In [69]: solts = []
            ...: solts_num = 32
            ...: 
            ...: for _ in range(solts_num):
            ...:     solts.append([])
            ...: def put(solts, key, value):
            ...:     i = hash(key) % solts_num
            ...:     p = -1
            ...:     for p, (k, v) in enumerate(solts[i]):
            ...:         if k == key:
            ...:             break
            ...:     else:
            ...:         solts[i].append((key, value))
            ...:         return 
            ...:     if p >=0:
            ...:         solt[i][p] = (key, value)
            ...: def get(solts, key):
            ...:     i = hash(key) % solts_num
            ...:     for k, v in solts[i]:
            ...:         if k == key:
            ...:             return v
            ...:     raise KeyError(k)
            ...: 
    版本3:类的实现
        In [74]: class Dict:
            ...:     def __init__(self, num):
            ...:         self.__solts__ = []
            ...:         self.num = num
            ...:         for _ in range(num):
            ...:             self.__solts__.append([])
            ...:     def put(self, key, value):
            ...:         i = hash(key) % self.num
            ...:         for p, (k, v) in enumerate(self.__solts__[i]):
            ...:             if k == key:
            ...:                 break
            ...:         else:
            ...:             self.__solts__[i].append((key, value))
            ...:             return
            ...:         self.__solts__[i][p] = (key, value)
            ...:     def get(self, key):
            ...:         i = hash(key) % self.num
            ...:         for k, v in self.__solts__[i]:
            ...:             if k == key:
            ...:                 return v
            ...:         raise KeyError(key)
            ...:     
    
        In [75]: d = Dict(32)
    
        In [76]: d.put('r', 2)
    
        In [77]: d.put('d', 2)
    
        In [78]: d.get('r')
        Out[78]: 2
    
    版本4:类的实现, 添加keys方法实现
        In [79]: class Dict:
            ...:     def __init__(self, num):
            ...:         self.__solts__ = []
            ...:         self.num = num
            ...:         for _ in range(num):
            ...:             self.__solts__.append([])
            ...:     def put(self, key, value):
            ...:         i = hash(key) % self.num
            ...:         for p, (k, v) in enumerate(self.__solts__[i]):
            ...:             if k == key:
            ...:                 break
            ...:         else:
            ...:             self.__solts__[i].append((key, value))
            ...:             return
            ...:         self.__solts__[i][p] = (key, value)
            ...:     def get(self, key):
            ...:         i = hash(key) % self.num
            ...:         for k, v in self.__solts__[i]:
            ...:             if k == key:
            ...:                 return v
            ...:         raise KeyError(k)
            ...:     def keys(self):
            ...:         ret = []
            ...:         for solt in self.__solts__:
            ...:             for k, _ in solt:
            ...:                 ret.append(k)
            ...:         return ret
            ...:     
    
        In [80]: d = Dict(32)
    
        In [81]: d.put('r', 2)
    
        In [82]: d.put('d', 2)
    
        In [83]: d.keys()
        Out[83]: ['d', 'r']
    

    开地址法

    i = hash(key) % solt 可以用相同的算法来做
    假设槽位有32个, 那么得到的值很有可能会有冲突, i为最后的该值处于哪个槽位。
    不同的是, 值冲突后的处理方法不同。

    i = fn(key, i) # 如果被占用, 就用算法去找下一个槽。如果槽还是被占用, 就会去找下一个槽。
    取值的时候, 用函数一个一个找下去。

    集合在底层的实现, 就是一个忽略了value的字典

  • 相关阅读:
    每日算法
    每日算法
    每日算法
    每日算法
    2020 蓝桥杯(省赛)校内模拟赛
    js 时间戳转特定格式的日期
    js正则表达式 replace替换url的参数
    7月/暑假集训总结1
    模板(ac):启发式合并
    [考试反思]0729NOIP模拟测试10
  • 原文地址:https://www.cnblogs.com/cishi/p/13041263.html
Copyright © 2011-2022 走看看