# -*- coding: utf-8 -*-

class Array(object):

    def __init__(self, size=32, init=None):
self._size = size
self._items = [init] * size def __getitem__(self, index):
return self._items[index] def __setitem__(self, index, value):
self._items[index] = value def __len__(self):
return self._size def clear(self, value=None):
for i in range(len(self._items)):
self._items[i] = value def __iter__(self):
for item in self._items:
yield item class Slot(object):
def __init__(self, key, value):
self.key, self.value = key, value class HashTable(object): UNUSED = None # 没被使用过
EMPTY = Slot(None, None) # 使用却被删除过 def __init__(self):
self._table = Array(8, init=HashTable.UNUSED) # 保持 2*i 次方
self.length = 0 @property
def _load_factor(self):
# load_factor 超过 0.8 重新分配
return self.length / float(len(self._table)) def __len__(self):
return self.length def _hash(self, key):
return abs(hash(key)) % len(self._table) def _find_key(self, key):
index = self._hash(key)
_len = len(self._table)
while self._table[index] is not HashTable.UNUSED:
if self._table[index] is HashTable.EMPTY:
index = (index*5 + 1) % _len
continue
elif self._table[index].key == key:
return index
else:
index = (index*5 + 1) % _len
return None def _find_slot_for_insert(self, key):
index = self._hash(key)
_len = len(self._table)
while not self._slot_can_insert(index):
index = (index*5 + 1) % _len
return index def _slot_can_insert(self, index):
return (self._table[index] is HashTable.EMPTY or self._table[index] is HashTable.UNUSED) def __contains__(self, key): # in operator
index = self._find_key(key)
return index is not None def add(self, key, value):
if key in self:
index = self._find_key(key)
self._table[index].value = value
return False
else:
index = self._find_slot_for_insert(key)
self._table[index] = Slot(key, value)
self.length += 1
if self._load_factor >= 0.8:
self._rehash()
return True def _rehash(self):
old_table = self._table
newsize = len(self._table) * 2
self._table = Array(newsize, HashTable.UNUSED) self.length = 0 for slot in old_table:
if slot is not HashTable.UNUSED and slot is not HashTable.EMPTY:
index = self._find_slot_for_insert(slot.key)
self._table[index] = slot
self.length += 1 def get(self, key, default=None):
index = self._find_key(key)
if index is None:
return default
else:
return self._table[index].value def remove(self, key):
index = self._find_key(key)
if index is None:
raise KeyError()
value = self._table[index].value
self.length -= 1
self._table[index] = HashTable.EMPTY
return value def __iter__(self):
for slot in self._table:
if slot not in (HashTable.EMPTY, HashTable.UNUSED):
yield slot.key class SetADT(HashTable): def add(self, key):
return super(SetADT, self).add(key, True) def __and__(self, other_set):
"""交集 A&B"""
new_set = SetADT()
for element_a in self:
if element_a in other_set:
new_set.add(element_a)
return new_set def __sub__(self, other_set):
"""差集 A-B"""
new_set = SetADT()
for element_a in self:
if element_a not in other_set:
new_set.add(element_a)
return new_set def __or__(self, other_set):
"""并集 A|B"""
new_set = SetADT()
for element_a in self:
new_set.add(element_a)
for element_b in other_set:
new_set.add(element_b)
return new_set def test_set_adt():
sa = SetADT()
sa.add(1)
sa.add(2)
sa.add(3)
assert 1 in sa
sb = SetADT()
sb.add(3)
sb.add(4)
sb.add(5) assert sorted(list(sa & sb)) == [3]
assert sorted(list(sa - sb)) == [1, 2]
assert sorted(list(sa | sb)) == [1, 2, 3, 4, 5] if __name__ == '__main__':
test_set_adt()

集合(python)的更多相关文章

  1. Java集合-Python数据结构比较

    Java list与Python list相比较 Java List:有序的,可重复的.(有序指的是集合中对象的顺序与添加顺序相同) Python list(列表)是有序的,可变的. Java Lis ...

  2. 面试基础知识集合(python、计算机网络、操作系统、数据结构、数据库等杂记)

    python python _.__.__xx__之间的差别 python中range.xrange和randrange的区别 python中 =.copy.deepcopy的差别 python 继承 ...

  3. 二叉树题目集合 python

    二叉树是被考察频率非常高的数据结构.二叉树是按照“父节点-左子树&右子树”这样的方式,由根节点不断向下扩展,形成一棵树的结构.二叉树经常被提到的三种遍历方式:前序遍历.中序遍历和后序遍历,既是 ...

  4. 【Python学习笔记】集合

    概述 集合的一般操作 内建函数进行标准操作集合 数学运算符进行标准操作集合 集合的应用 概述 python的集合(set)是无序不重复元素集,是一种容器.集合(set)中的元素必须是不可变对象,即可用 ...

  5. python 基础 set 集合类型补充

    为啥今天又重提这个数据类型呢?平时用的少,等要用起来的时候才发现,自己对这块啥都不知道了,so,今天就把这块再梳理一下咯. 一.set集合,是一个无序且不重复的元素集合.这一点是非常重要的. 二.集合 ...

  6. Python 全栈开发二 python基础 字符串 字典 集合

    一.字符串 1,在python中,字符串是最为常见的数据类型,一般情况下用引号来创建字符串. >>ch = "wallace" >>ch1 = 'walla ...

  7. Python基础数据类型之集合

    Python基础数据类型之集合 集合(set)是Python基本数据类型之一,它具有天生的去重能力,即集合中的元素不能重复.集合也是无序的,且集合中的元素必须是不可变类型. 一.如何创建一个集合 #1 ...

  8. Python学习——集合

    集合 python中的集合和数学上集合具有基本相同的性质,此处不再赘述. 1.创建集合的两种方法 #直接创建 num={1,2,3,4,5} #利用set方法创建 num1=set([1,2,3,4, ...

  9. Python 学习 第14篇:数据类型(元组和集合)

    元组和集合是Python中的基本类型 一,元组 元组(tuple)由小括号.逗号和数据对象构成的集合,各个项通过逗号隔开,元组的特点是: 元组项可以是任何数据类型,也可以嵌套 元组是一个位置有序的对象 ...

随机推荐

  1. 【Tools】ModbusSlave 7.0和ModbusPoll 7.0官网最新软件+注册码

    某宝1.5元淘的:有币的求赏,小弟下载缺币.没币的从附件下载. 赏币地址:https://download.csdn.net/download/qq_18187161/10724794 谢谢! 无币百 ...

  2. unix 命令

    ubuntu  命令窗口的打开 打开命令行窗口: Ctrl+Alt+T 在打开的命令行窗口中打开一个新的Tab: Ctrl+Shift+T 在同一窗口的Tab间切换: Ctrl+Page Up 或者 ...

  3. [C语言]给定直角三角形面积和斜边长

    [A题]   翘课的HugeGun_ 时间限制:1000ms   内存限制:65536kb 题目描述 HugeGun学姐很喜欢翘课.不幸的是,这一次她被发现了. 老师让她打扫了教室.当她把扫把靠在墙上 ...

  4. java8中常用的新功能

    Lambda表达式的用法,并行流.Optional.循环.线程池等

  5. 深入理解Flink核心技术及原理

    前言 Apache Flink(下简称Flink)项目是大数据处理领域最近冉冉升起的一颗新星,其不同于其他大数据项目的诸多特性吸引了越来越多人的关注.本文将深入分析Flink的一些关键技术与特性,希望 ...

  6. 阿里云服务器安装mysql8遇到的问题

    1.提供一个离线mysql下载路径:http://mirrors.163.com/mysql/Downloads/MySQL-8.0/ 2.在线mysql8安装: 2.1 下载mysql: wget ...

  7. Zuul【工作原理】

    zuul的核心逻辑都是由一系列filter过滤器链实现的,但是filter的类型不同,执行的时机也不同,效果自然也不一样,主要特点如下: filter的类型:filter的类型,决定了它在整个filt ...

  8. jdbc连接oracle的三种方法

    jdbc连接oracle的三种方法 使用service_name,配置方式:jdbc:oracle:thin:@//<host>:<port>/<service_name ...

  9. C++ 生成随机数总结 & C++ rand 函数使用方法

    1. 产生[0,b]之间的随机数 rand()*b / RAND_MAX; 2. 产生[-a,0]之间的随机数 rand()*(-a) / RAND_MAX; 3. 产生[a,b]之间的随机数 a + ...

  10. Django基础十一之认证系统

    一 auth模块 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个 ...