2.1 数组结构
一维数组(one-dimensional array)是多个元素按照一定的顺序,储存在内存的连续的字节当中,并允许对每一个元素的任意访问。
对数组中元素的访问,是通过指针来完成。(类似于数学中的下标)
2.1.1 为什么学习数组
数组与python中列表的区别:
- 数组的相关操作较少,而列表的操作较多;(感觉挺牵强的)
- 数组一经创建,其长度不能改变,而列表可以随意增删元素,甚至将另一个列表合并进来,即列表的长度是可变的。(主要区别)
- 数组占用的内存空间较小,而列表占用的内存空间较大,往往比列表本身的长度要打,这也是列表长度可变的原因。
在解决问题时,采用数组还是列表,得依据问题而定。数组适合于已知序列最大长度的相关问题,而列表适用于长度会发生变化的问题。
2.1.2 数组ADT
数组ADT含有以下方法:
- Array(size):创建长度为size的数组,并将数组中每一个元素初始化为None;
- length():获取数组长度;
- getitem(index):返回指针index指向的数组元素,可通过[]操作符实现对元素的访问;
- setitem(index, value):将给定指针index指向的数组元素赋值为value;
- clear(value):将整个数组的元素全部赋值为value;
- iterator():创建迭代器。
#-*-coding: utf-8-*-
# 创建定长数组,填入随机数,并打印数组
from myarray import Array
import random
valueList = Array(100)
for i in range(len(valueList)):
valueList[i] = random.random()
for value in valueList:
print value
#-*-coding: utf-8-*-
# 数文件中每个字母出现次数,可打印的ASCII字符共有127个,因此可以使用数组,将每个字母出现的次数存入数组的每一项中。
from myarray import Array
theCounters = Array(127)
theCounters.clear(0)
theFile = open('atextfile.txt', 'r')
for line in theFile:
for letter in line:
code = ord(letter)
theCounters[code] += 127
theFile.close()
for i in range(26):
print "%c - %4d\t%c - %4d" % (chr(65+i), theCounters[65+i], chr(97+i), theCounters[97+i])
2.1.3 实现数组ADT
ctypes模块
这一模块为python使用者访问并使用C语言及其相关库中提供的多种数据类型。我们用这一模块来在python中实现数组ADT。
#-*-coding: utf-8-*-
# 使用ctypes模块实现数组ADT
import ctypes
class Array(object):
# 通过长度创建数组
def __init__(self, size):
assert size > 0, "Array size must be > 0"
self._size = size
# 创建数组
PyArrayType = ctypes.py_object * size
self._elements = PyArrayType()
# 对每个元素初始化为None
self.clear(None)
def __len__(self):
return self.size
# 通过指针访问元素
def __getitem__(self, index):
assert 0 <= index < len(self), "Array subscript out of range"
return self._elements[index]
# 将值放入数组的指定的元素中
def __setitem__(self, index, value):
assert 0 <= index < len(self), "Array subscript out of range"
self._elements[index] = value
# 清空数组中的所有值,并将所有元素设为给定值
def clear(self, value):
for i in range(len(self)):
self._elements[i] = value
# 返回数组的迭代器,以便用于遍历元素
def __iter__(self):
return _ArrayIterator(self._elements)
# 数组的迭代器
class _ArrayIterator(object):
def __init__(self, theArray):
self._arrayRef = theArray
self._curNdx = 0
def __iter__(self):
return self
def __next__(self):
if self._curNdx < len(self._arrayRef):
entry = self._arrayRef[self._curNdx]
self._curNdx += 1
return entry
else:
raise StopIteration