Nim语言实现行主描述与列主描述的矩阵

130 阅读1分钟

Nim编程入门

这一节,我们使用行主描述与列主描述,分别实现简单的矩阵底层数据结构。

构造矩阵

我们有两种方式描述矩阵的底层数据结构。一种是使用二维数组,来存储底层数据。另一种是使用一维数组,再通过行主映射或者列主映射将二维数组映射到这个一维数组上。

这两种方式的差异之一,是空间的使用。 假设我们建立一个 4 * 5 的 int 型矩阵(int 为 8 个字节)。Nim 语言中的指针需要使用 8 个字节来表示。使用一维数组,我们总共花费 8 + 8 * 4 * 5 = 168 个字节。使用二维数组,我们总共需要花费 8 + 8 * 4 * 5 + 4 * 8 = 200 个字节,多出来四个指针所占的空间。显然,使用一维数组更节省空间。

其二,访问元素的快慢,需要看在 Nim 语言中,是使用一维映射函数定位指针,再用指针定位元素的方案快[二维数组],还是使用二维映射函数定位元素的方案快[一维数组]。

import sequtils


type
  # 二维数组
  RMatrix*[T] = object
    data: seq[seq[T]]
    rows: int
    cols: int
  # 一维数组
  CMatrix*[T] = object
    data: seq[T]
    rows: int
    cols: int

proc newRMatrix*[T](rows, cols: int): RMatrix[T] {.noinit.} =
  result.rows = rows
  result.cols = cols
  result.data = newSeqWith(cols, newSeqUninitialized[T](rows))

proc newCMatrix*[T](rows, cols: int): CMatrix[T] {.noinit.} =
  result.rows = rows
  result.cols = cols
  result.data = newSeqUninitialized[T](rows * cols)