python 利用dict构造多重集合multiset类
python有set()结构,但是set不允许重复元素出现。如果我们的任务像优先队列那样经常访问最大最小值,那么使用set要比list快。而字典dict的键是set组织的,我们利用data作为key,出现次数作为value可以自己构造一个multiset类。
对照C++的multiset类,设计以下的方法:构造;元素个数,是否为空;修改:插入,删除,清空;取值:最大、最小、计数、存在性.
由于python不能做函数重载,所以没有对multiSet的构造函数添加从其它数据结构的构造方法。但可以视需要再添加。
由于使用字典的值表示键的出现次数,若要求多重集合的元素数可以遍历整个字典的值并累加,但如果字典的键比较多并且访问集合元素数比较频繁,这一步是相当耗时的,所以额外定义一个变量专门保存整个多重集合的大小。
修改集合需要插入、删除和清空。插入时检查当前键是否存在于字典中,若存在则相应值+=1,否则建立这个键并赋值为1。删除操作类似地,检查待删除元素是否存在于字典中,若不存在则什么也不做。存在时若此值为1则删除此键,否则此值自减1。清空操作则是将字典置空并将集合大小置0.
取数操作有最大、最小、查找、计数。直接对字典取max是取的键的最大值,这恰与我们所需相符。字典的键本身是set组织的,用关键字in查找是O(logN)的复杂度,比线性表快。count同样是O(logN)的复杂度。
class multiSet: def __init__(self): self.container = {} self.capSize = 0 # capacity def size(self): return self.capSize def isEmpty(self): return self.capSize==0 # modifiers: def insert(self,v): self.capSize+=1 if(v in self.container): self.container[v]+=1 else: self.container[v]=1 def remove(self,v): if v in self.container: self.capSize-=1 if(self.container[v]==1): del self.container[v] else: self.container[v]-=1 def clear(self): self.capSize = 0 self.capacity = {} # Operations: def max(self): return max(self.container) def min(self): return min(self.container) def find(self,v): return v in self.container def count(self,v): if v in self.container: return self.container[v] else: return 0