【问题标题】:Python Hash: Insert MethodPython 哈希:插入方法
【发布时间】:2015-04-11 08:04:47
【问题描述】:

我一直在尝试为我的MyHashTable: 类编写一个insert(self, key): 方法。

它应该使用线性探测来处理冲突解决方案。如果键已经在表中,则该方法返回-2。如果键不在表中并且存在空槽,则将键输入到hash_function 返回的空槽号中,并返回该槽号。如果键不在哈希表中并且没有空槽,则返回-1

这是我的课:

class MyHashTable:

def __init__(self, capacity):
    self.capacity = capacity
    self.slots = [None] * self.capacity

def __str__(self):
    return str(self.slots )

def __len__(self):
    count = 0
    for i in self.slots:
        if i != None:
            count += 1
    return count

def hash_function(self, key):
    i = key % self.capacity
    return i

def insert(self, key):
    slot = self.hash_function(key)
    if key in self.slots[slot]:
        return -2
    elif key in self.slots[slot] == False:
        return -1
    else:
        self.slots[slot].append(key)
        return slot

测试是:

x = MyHashTable(2)
print("Add 3, return:", x.insert(3))
print("Hashtable:", x)
print("Add 3, return:", x.insert(3))  #duplicate
print("Hashtable:", x)

结果应该是:

Add 3, return: 1
Hashtable: [None, 3]
Add 3, return: -2
Hashtable: [None, 3]

我尝试了一些方法,但不断收到错误消息。 “Nonetype”不可迭代。

【问题讨论】:

  • 您的代码中没有插入方法。这使得诊断您遇到的问题有点困难:-)
  • 是的。我需要写一个.....
  • 您不会从添加的代码中得到“NoneType is not iterable”,pass 没有迭代随机集合的习惯 :-) 我建议您添加一个尝试。
  • 当您收到错误消息时,最好发布 full 错误消息(在代码块中),从 Traceback 行开始;并发布发生该错误的代码部分。如果您这样做了,那么回答您问题原因的人会立即明白。
  • FWIW,您收到了 "Nonetype" is not iterable 消息,因为您的 insert() 正试图将 key 附加到 None。实际上,您的 insert() 的逻辑似乎将 self.slots 视为列表列表。这组织哈希表的一种合法方式,但它与您班级的其他人不一致。

标签: python hash insert hashtable


【解决方案1】:

好的,我们必须从这里的首要原则出发。以下是insert 需要为您的情况做的事情:

  1. 通过调用hash_function获取基于密钥的初始槽号。保存此插槽位置以备后用,我们将需要它来检测哈希表是否已满。
  2. 检查当前槽是否为空。如果是,则在该点插入密钥并返回成功。
  3. 如果密钥已经在该槽中,则返回 -2,它是重复的。
  4. 否则,该插槽中有一些 other 键,因此将插槽推进到下一个(如果超出容量,则绕回插槽零)。如果您已循环回到第 1 步中保存的原始插槽,请在表已满时返回 -1。
  5. 否则返回第 2 步并继续寻找密钥或空槽。

这基本上就是使用线性探测进行散列的预期工作方式。

我敦促您自己尝试并实现它,您将成为一个更好的编码员,付出一些血、汗和泪 :-)


完成后,看看它与我最初的剪辑相比如何:

def insert(self, key):
    slot = self.hash_function(key)
    orig = slot
    while True:
        if self.slots[slot] is None:
            self.slots[slot] = key
            return slot

        if self.slots[slot] == key:
            return -2

        slot = (slot + 1) % self.capacity
        if slot == orig:
            return -1

我保留在其中留下某些细微错误的权利,以防这是您应该自己做的功课(实际上,我只是粗略地测试了一下,所以它可能不是完全没有错误,但是它与我提供的算法相匹配,因此应该接近)。

【讨论】:

  • 我不明白你为什么这么做slot = (slot + 1) % self.capacity。你知道使用类似的类来学习散列的任何好的资源吗?
  • @Newbie,这是取模运算符,相当于slot = slot + 1后跟if slot == self.capacity: slot = 0。当您超出数组末尾时,它会简单地环绕到数组的开头。
【解决方案2】:

只要您没有返回任何内容,您的 insert() 就不会返回可迭代对象。

我猜你想打印的是 MyHashTable x 本身。否则你需要将return self 附加到insert() 的定义中,虽然它看起来很奇怪。

【讨论】:

    猜你喜欢
    • 2015-06-25
    • 2017-03-28
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2011-01-29
    • 2015-06-10
    • 2014-11-01
    相关资源
    最近更新 更多