3.3 多维数组
3.3.1 多维数组ADT
多维数组包含了一组通过多个维度组织起来的数据。相应的索引是元组(i1, i2, ..., in)。
- MultiArray(d1, d2, .., dn):创建多维数组,并将所有值初始化为None,注意要传入可变参数 。维度最高从d1开始,一直到dn;
- dims():返回维度数;
- clear(value):将多维数组中所有数值设定为给定值;
- getitem(i1, i2, ..., in):返回给定 索引的值,也是传入可变参数;
- setitem(i1, i2, ..., in, value):将给定索引的值设定为给定值value。
在大多数编程语言中,多维数组是以一维数组的形式创建并储存在内存中。
数组储存(以二维数组为例)
行主序(row-major order):二维数组的数据按照一行一行地连续排列在底层的一维数组中,如下图:
列主序(column-major order):二维数组的数据按照一列一列地连续排列在底层的一维数组中,如下表:
索引计算(偏移量计算)
偏移量(offset):多维数组的某一项在底层数组中的索引。
二维数组的情形:index2(i, j)
= i ∗n
+j
三维数组的情形:index3(i1,
i2, i3) =i1∗
(d2∗
d3) +i2∗
d3+
i3
n维数组的情形:index(i1,i2,...,in)
= i1∗
f1+
i2
∗ f2+
· · · +
in−1∗
fn−1+
in
∗1
其中计算因子
3.3.3 可变参数(已会,略)
3.3.4 多维数组的实现
#-*-coding: utf-8-*-
# 多维数组的实现
from myarray import Array
class MultiArray(object):
# 创建多维数组实例
def __init__(self, *dimensions):
assert len(dimensions) > 1, "The array must have 2 or more dimensions."
self._dims = dimensions
# 计算多维数组的总元素个数
size = 1
for d in dimensions:
assert d > 0, "Dimensions must be > 0."
size *= d
# 创建一维数组,以储存多维数组的元素
self._elements = Array(size)
# 创建一维数组,以存储计算因子
self._factors = Array(len(dimensions))
self._computeFactors()
# 返回多维数组的维度
def numDims(self):
return len(self._dims)
# 返回给定维度的长度
def length(self, dim):
assert 1 <= dim < len(self._dims), "Dimensions component out of range."
return self._dims[dim - 1]
# 将整个多维数组的所有元素设定为给定值
def clear(self, value):
self._elements.clear(value)
# 返回给定索引的元素
def __getitem__(self, ndxTuple):
assert len(ndxTuple) == self.numDims(), "Invalid # of array subscripts."
index = self._computeIndex(ndxTuple)
assert index is not None, "Array subscripts out of range."
return self._elements[index]
# 将给定索引的元素设定为给定值
def __setitem__(self, ndxTuple, value):
assert len(ndxTuple) == self.numDims(), "Invalid # of array subscripts."
index = self._computeIndex(ndxTuple)
assert index is not None, "Array subscripts out of range."
self._elements[index] = value
# 根据给定的索引,计算一维数组的偏移量
def _computeIndex(self, idx):
offset = 0
for j in range(len(idx)):
# 确保传入的索引有效
if idx[j] < 0 or idx[j] >= self._dims[j]:
return None
else:
offset += idx[j] * self._factors[j]
return offset
# 计算各维度相关计算因子
def _computeFactors(self):
pass
注意在多维数组中,没有长度这一说法,只有在某一维度上的长度,因此不能使用len()函数,必须传入某一维度作为参数。