python当中的字典类型就是映射,本节主要实现映射这一ADT。
3.2.1 映射ADT
映射是通过关联唯一的键来储存数据记录的容器。这些键组件必须可以相互比较(不能相互比较,怎么显示唯一性)。具有如下方法:
- Map():创建映射;
- length():返回映射中键值对数目;
- contains(key):判断映射中是否存在给定键;
- add(key, value):添加键值对,如果键不存在,返回True,显示添加成功,若键已存在,则修改相应值,返回False,表示键已存在,值已修改;
- romove(key):删去映射中给定键的键值对,若键不存在,则引发异常;
- valueOf(key):返回映射中给定键的值,若键不存在,则引发异常;
- iterator():返回可迭代键的迭代器。
实现映射可使用列表和数组,但数组的长度是固定的,显然映射的长度可任意长短,所以列表是更好的选择。
我们可以使用两个列表来实现映射,一个列表用来储存键,另一个列表来储存值,这两个列表的元素必须一一对应。
书中使用一个列表来实现映射,每一对键值对通过一个储存类来实现,而列表中的每一个元素则是储存类实例的引用。
#-*-coding: utf-8-*-
# 使用单个python列表实现映射ADT,每一对键值对用储存类存储,而每一个储存类实例对象则存储在列表的每一项中
class Map(object):
def __init__(self):
self._entryList = list()
# 映射的键值对数目
def __len__(self):
return len(self._entryList)
# 判断给定键是否在映射中
def __contains__(self, key):
ndx = self._findPosition(key)
return ndx is not None
# 添加新键值对,若键不存在,则返回True,若键已存在,则修改值,返回False
def add(self, key, value):
ndx = self._findPosition(key)
if ndx is not None: # 键已存在
self._entryList[ndx].value = value
return False
else:
entry = _MapEntry(key, value)
self._entryList.append(entry)
return True
# 返回给定键的值
def valueOf(self, key):
ndx = self._findPosition(key)
assert ndx is not None, "Invalid map key."
return self._entryList[ndx].value
# 删除键值对
def remove(self, key):
ndx = self._findPosition(key)
assert ndx is not None, "Invalid map key."
self._entryList.pop(ndx)
# 返回迭代器
def __iter__(self):
return _MapIterator(self._entryList)
# 帮组寻找给定键在底层列表中的索引,如果底层列表不含该键,则返回None。
def _findPosition(self, key):
for i in range(len(self)):
if self._entryList[i].key == key:
return i
return None
# 储存类
class _MapEntry(object):
def __init__(self, key, value):
self.key = key
self.value = value
class _MapIterator(object):
def __init__(self, theMapList):
self._mapRef = theMapList
self._curNdx = 0
def __iter__(self):
return self
def next(self):
if self._curNdx < len(self._mapRef):
entry = self._mapRef[self._curNdx]
self._curNdx += 1
return entry
else:
raise StopIteration