Lisp语言:二维数组和多维数组

来源:互联网 发布:java项目业绩怎么写 编辑:程序博客网 时间:2024/04/27 15:37

很多情况下只有一维数组是不够用的,有时我们需要使用二维数组甚至是多维数组。

Lisp中二维数组的使用和一维数组很接近,都是使用make-array函数来创建。

创建一维数组的样例如下:

(setf test-array-1 (make-array 10 :initial-element "xxx"))
而创建二维数组的样例看起来非常相似:

(setf test-array-2 (make-array '(3 5) :initial-element "xxx"))

比较两行语句可以发现,创建二维数组和创建一维数组不同的就是make-array后面跟着的参数,也就是维度的参数。

创建一维数组时“维度参数”是一个数字,指定数组的长度。

创建二维数组时“维度参数”是一个列表,像这样:'( 3  5)。因为我们到目前为止还没有详细讨论列表,所以不对这种形式做详细分析。我们先不管为什么,反正先记住定义二维数组时“维度参数”是一个单引号后面跟一对括号,括号中两个数字,分别是两个维度的长度。

所以上面的样例代码定义了一个3*5的二维数组。


和一维数组一样,访问二维数组的元素可以使用函数aref,不过参数多一个。下面是访问test-array-2 数组中的元素的样例:

(aref test-array-2 1 3)

以上代码获得test-array-2这个二维数组中第二行第四列的元素,或者说是取得test-array-2数组中下标为“1,3”的元素。

同样,需要注意Lisp中数组下标是以0开始计算的。

如果需要对Lisp中的二维数组进行遍历,依赖length函数是不行的了,在不知道维度的情况下单纯靠一个二维数组的长度是无法遍历它的。事实上如果在length函数中传入一个二维数组的话系统会报错的。

希望获取一个二维数组的维度可以使用array-dimensions函数,注意array-dimension后面有个s。

array-dimentions函数会返回一个列表,保存着目标数组不同维度的长度。

按以上样例对test-array-2的定义,下面的样例代码会返回“(3 5)”:

(array-dimensions test-array-2)
知道了一个二维数组所有维度的长度,结合loop循环就可以对一个二维数组进行遍历了,不过需要对arrar-dimensions函数的返回值进行处理,以分别得到第一维度和第二维度的长度。

其实现实中不用这么麻烦,Lisp提供了另一个函数获取二维数组,甚至是多维数组不同维度的长度,就是函数array-dimension,注意array-dimension后面是不带s的。

如,下面的代码可以获得数组test-array-2第一个维度的长度。

(array-dimension test-array-2 0)
对应地,下面的代码可以获得数组test-array-2第二个维度的长度。

(array-dimension test-array-2 1)

所以,下面的代码就可以对数组test-array-2进行遍历,输出所有元素的值:

(loop for i from 0 below (array-dimension test-array-2 0) do                 (loop for j from 0 below (array-dimension test-array-2 1) do                        (format *query-io* "element ~a ~a is ~a ~%"                                i                                j                                (aref test-array-2 i j))))
注意以上代码使用loop循环时使用了below而不是to做为循环条件

loop for i from 0 to x 相当于是java中的 for (int i=0 ;i==x;i++)

而loop for i from 0 below x相当于是java中的 for (int i=0 ;i<x ;i++)


最后,如果希望对数组某个元素进行赋值操作,可以使用setf函数结合aref函数的方法,如:

(setf (aref test-array-2 1 3) "yyyyyyy")
以上代码对test-array-2数组下标为(1,3)的元素进行赋值,值为“yyyyyyy”


以下为二维数组定义,修改,遍历的完整代码和执行结果截图:

(defun array-test-2 ()        (setf test-array-2 (make-array '(3 5) :initial-element "xxx"))         (setf array-dim-2 (array-dimensions test-array-2))        (format *query-io* "Dimension of array-test-2 is: ~a ~%" array-dim-2)        (setf (aref test-array-2 1 3) "yyyyyyy")        (setf (aref test-array-2 2 3) "ttttttt")        (loop for i from 0 below (array-dimension test-array-2 0) do                 (loop for j from 0 below (array-dimension test-array-2 1) do                        (format *query-io* "element ~a ~a is ~a ~%"                                i                                j                                (aref test-array-2 i j)))))



知道了二维数组的使用方法,三维数组甚至是多维数组就比较简单了,使用方法类似,就是维度参数不同。

如四维数组的定义如下:

(setf test-array-3 (make-array '(3 5 6 9) :initial-element "xxx"))

获取test-array-3第4个维度的长度的代码如下:

(array-dimension test-array-3 3)

获得test-array-3数组中下标为( 2 2 2 2)元素的代码如下:

(aref test-array-3 2 2 2 2 )