6.00.2x学习笔记Week2 Part1
Probability
🎲揉5次,不出现一个1的可能性是:(5/6)5
至少出现一次1的可能性就是:1 - (5/6)5
100个学生在一个教室,多大可能性这100个人中今天有人过生日?
答:1 - (364/365)100
Hashing
chr()根据整数返回对应的字符,也就是讲ascii转换为字符
unichr()将整数返回成unicode字符
ord()将字符转换成ascii码
从为什么会出现hash讲起。
convert the key to an integer and then use that integer to index into a list, which can be done in constant time because values of any object can be easily converted to an integer.
因为如果把所有的string都转换成integer会很大,所以采取取余数的办法。但是这样会产生collison,这个collison是可以接受的。
We have collisions because a hash function is a many-to-one mapping. The whole point was to take a very large space and map each element in that space into a much smaller space.
把table变大,collison就会少,以空间换时间。
接下来看一下有多大的机率会产生collison。
import random
class intDict(object):
"""A dictionary with integer keys"""
def __init__(self, numBuckets):
"""Create an empty dictionary"""
self.buckets = []
self.numBuckets = numBuckets
for i in range(numBuckets):
self.buckets.append([])
def addEntry(self, dictKey, dictVal):
"""Assumes dictKey an int. Adds an entry."""
hashBucket = self.buckets[dictKey%self.numBuckets] #确定第几个bucket
for i in range(len(hashBucket)): #遍历这个bucket中的元素
if hashBucket[i][0] == dictKey: #如果有相同的key
hashBucket[i] = (dictKey, dictVal) #就更新
return #返回为空表示结束这个method并且不执行下面的命令
hashBucket.append((dictKey, dictVal)) #如果检查过后该bucket没有collison,则把这个tuple添加到该bucket。
def getValue(self, dictKey):
"""Assumes dictKey an int. Returns entry associated
with the key dictKey"""
hashBucket = self.buckets[dictKey%self.numBuckets]
for e in hashBucket:
if e[0] == dictKey:
return e[1]
return None
def __str__(self):
res = ''
for b in self.buckets:
for t in b:
res = res + str(t[0]) + ':' + str(t[1]) + ','
return '{' + res[:-1] + '}' #res[:-1] removes the last comma
#有29个buckets,要塞20个东西进去,key是随机生成的。通过除以29得余数来确定index,也就是存入这29个当中的第几个bucket。
D = intDict(29)
for i in range(20):
#choose a random int in range(10**5)
key = random.choice(range(10**5))
D.addEntry(key, i)
print '\n', 'The buckets are:'
for hashBucket in D.buckets: #violates abstraction barrier
print ' ', hashBucket
这时再print D
,就会看到生成的结果。
>>> {59340:1,53628:10,94664:17,1981:19,85967:14,86490:8,52270:9,23272:13,6918:5,13704:6,85104:3,3266:11,64630:15,55438:18,61589:0,28358:2,72409:4,9567:7,76674:12,5653:16}
当我们说有n个buckets。要放K个东西进去。
放入第一个不可能有collison,因为所有的buckets都是空的。也就是说冲突的可能性是0。
当放第一个的时候,不冲突的可能性是1
当放第二个的时候,不冲突的可能性是(n-1)/n
当放第三个的时候,不冲突的可能性是(n-2)/n
当放第K个的时候,不冲突的可能性是(n-(K-1))/n
这时候,如果我们要问,如果把K个东西都放进去,出现冲突的可能性是多少。思考方法与先前说的生日问题一样。也就是说,只有两种可能,一种是冲突了,一种是没冲突,两者之和代表所有可能性,所以是1。
也就是说出现冲突的可能性 = 1 - 上述不肯能的乘积。
用代码表示:
def collision_prob(numBuckets, numInsertions):
'''
Given the number of buckets and the number of items to insert,
calculates the probability of a collision.
'''
prob = 1.0
for i in range(1, numInsertions):
prob = prob * ((numBuckets - i) / float(numBuckets))
return 1 - prob
Read more: