对称二维阵列

时间:2012-02-12 06:36:04

标签: lisp common-lisp

测试数组是否是二维的代码是什么?对于一个维度,我知道逆转列表将起作用。对于二维,我知道相反的行/列必须相同。换句话说,[1] [2]必须等于[2] [1],依此类推。

(defun symmetric-check(list)(相等列表(反向列表)))

3 个答案:

答案 0 :(得分:3)

首先,如果您需要随机访问,使用列表列表实现矩阵效率很低,因为使用二维数组会花费O(n + m)而不是更便宜的O(1)

要检查对称性,首先要确保矩阵是正方形,然后您只需要检查所有对的元素m_ij是否等于元素m_ji

由于您需要检查所有对是否对称,因此仅考虑i > j以避免每次测试两次(>而不是>=是有意义的,因为显然m_ii是相等的对自己而言。

另外,检查对称性并不需要考虑主对角元素。

(defun symmetric (m)
  (let ((rows (array-dimension m 0))
        (cols (array-dimension m 1)))
    (when (= rows cols)
      (dotimes (i rows T)
        (dotimes (j i)
          (unless (= (aref m i j) (aref m j i))
            (return-from symmetric NIL)))))))

(let ((m (make-array (list 5 5) :initial-element 0)))
  (dotimes (i 5)
    (dotimes (j 5)
      (setf (aref m i j) (* (1+ i) (1+ j)))))
  (print m)
  (print (symmetric m))
  (setf (aref m 3 2) 9)
  (print m)
  (print (symmetric m)))

答案 1 :(得分:2)

这取决于你对称的定义。

在线性代数中,矩阵称为对称iff它等于它的转置(这相当于说 M [i,j] = M [j,i] 对于所有 j )。因此,

(defun matrix-symmetric-p (m)
  (equal m (transpose-matrix m)))

(defun transpose-matrix (m)
  ;; implement this
  ...)

我强烈建议使用实际的数组,因为它可以使这样的事情变得更容易,更有效率。

(defun matrix-symmetric-p (m)
  (loop for i from 0 below (array-dimension m 0)
        always
          (loop for j from 0 below (array-dimension m 1)
                always
                  (= (aref m i j) (aref m j i)))))

答案 2 :(得分:1)

然而,标题含糊不清,鉴于你的例子,模拟可能是这样的:

(defun symmetric-2d-list-p (list)
  (equal (reverse (mapcar #'reverse list)) list))

(symmetric-2d-list-p '((1 1 1) (2 2) (3) (2 2) (1 1 1))) ; T
(symmetric-2d-list-p '((2 1 2) (2 2) (3) (2 2) (2 1 2))) ; T
(symmetric-2d-list-p '((1 1 1) (2 2) (3 4) (2 2) (1 1 1))) ; NIL

但你真的想澄清一下,因为2d数组是完全不同的东西,然后是包含列表的列表。

它肯定是一个更好的答案,不需要创建其他列表的答案。因为你原来的例子,我真的这样做了。希望有人会发布更优的版本。