2012-02-12 5 views
3

배열이 2 차원인지 여부를 테스트하는 코드는 무엇입니까? 한 차원의 목록을 뒤집는 것이 효과가 있다는 것을 알고 있습니다. 2 차원의 경우 반대 행/열이 동일해야합니다. 다른 말로하면 [1] [2]는 반드시 [2] [1]과 같아야합니다.대칭 2 차원 배열

(defun는 대칭 검사 (목록) (동일 목록 (리스트 역))) 귀하의 예제 주어진는

+0

어레이 (setf의에 도착 (메이 배열 '(2) 초기 내용'((1 2) (2 3))))이 코드가 충돌 할 비 스퀘어 행렬 – Tequila

답변

2

대칭의 정의에 따라 다릅니다. 이 (이 말 동등의 전치 같다 IFF에 선형 대수학

은 행렬은 대칭이라고하는 M [I, J = M [J, I] 모든 위한 IJ). 따라서, 더 쉽고 훨씬 효율적으로 수행 할 수 있기 때문에 실제 배열을 사용하는 것이 좋습니다. 그러나 실제 배열을 사용하는 것이 좋습니다. 그는 bidimensional 배열을 사용하는 대신 저렴 O(1)O(n + m)을 요하기 위하여려고하고 있기 때문에 당신이 랜덤 액세스를 필요로하는 경우 목록의 목록을 사용하여 매트릭스를 구현하는 모든

(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))))) 
+0

... 또한 각 쌍을 두 번 확인하고 있습니다. 왜 구문이 사실상 lispier'dotimes'보다 더 자세한 경우에도'loop'를 사용합니까? – 6502

+0

@ 6502 참이지만, 내가 사용한 대칭의 정의는 어쨌든 비 정사각형 행렬에서는 의미가 없습니다. 'dotimes'는'block'과'return-from' ('always' 지시어를 사용했음을 주목하십시오)을 사용해야하고, 따라서 의미 상 조금 더 못 생길 것입니다. –

+0

필요한 테스트를 통해 "실제 배열"을 넣었습니다. 감사, – Tequila

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 배열은 완전히 다른 것들이고 목록을 포함하는 목록이기 때문에 정말로 명확히하고 싶습니다.

분명히 추가 목록을 만들 필요가없는 더 나은 대답 일 수 있습니다. 나는 원래의 예 때문에이 방법으로 그것을 실제로했다. 다행히 누군가가 더 최적의 버전을 게시 할 것입니다.

3

먼저 비효율적이다.

대칭을 확인하려면 먼저 행렬이 사각형인지 확인한 다음 모든 요소에 대해 m_ij 요소가 m_ji과 동일한 지 확인해야합니다.

당신은 (명확하게 m_ii 자체와 동일하기 때문에 >하지 >=)를 두 번 각각의 시험을 수행 피하기 위해 단지 i > j을 고려하는 것이 합리적 대칭성에 대한 모든 쌍을 확인이 필요하기 때문에.

대칭을 검사하는 추가 보너스는 주요 대각선 요소를 고려하지 않아도됩니다.

(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)))