배열

배열 에서 Common Lisp

6개의 연습 문제

배열 소개

Common Lisp에서도 다른 언어들과 마찬가지로 배열은 정수 인덱스로 접근하는 원소들의 집합이에요. 원소들은 서로 다른 타입일 수 있어요. 배열은 1차원에 그치지 않고 다차원일 수도 있어요.

만들기

make-array로 배열을 만들 수 있어요. 옵션이 많지만, 간단한 형태로도 모든 원소를 하나의 값으로 초기화한 N차원 배열을 만들거나, 다른 시퀀스(리스트 같은)의 값들로 초기화한 배열을 만들 수 있어요. 첫 번째 인자는 각 차원의 크기를 나열한 리스트예요.

(make-array '(4) :initial-element 3)    ; => #(3 3 3 3)
(make-array '(2 2) :initial-element 'x) ; => #2A((X X) (X X))
(make-array '(3 3 3) 
  :initial-contents '(((a b c) (d e f) (g h i)) 
                      ((j k l) (m n o) (p q r)) 
                      ((s t u) (v w x) (y z &))))
                                        ; => #3A(((A B C) (D E F) (G H I))
                                                 ((J K L) (M N O) (P Q R))
                                                 ((S T U) (V W X) (Y Z &)))

(N차원 배열이 차원 수와 함께 출력되는 점에 주목해 봐요.)

배열이 출력되는 형식을 그대로 써서 배열을 만들 수도 있어요:

#(x y z)         ; => #(X Y Z)
#2A((1 2) (3 4)) ; => #2A((1 2) (3 4))

원소에 접근하기

벡터의 원소에 접근하려면 aref를 사용해요. 인덱스는 0부터 시작해요. 제공하는 인덱스의 개수는 배열의 랭크와 같아야 해요.

(aref #2A((1 2 3) (3 4 5)) 1 0) ; => 3
(aref #3A(((a b) (c d)) 
          ((e f) (g h)) 
          ((t u) (v w))) 
      2 0 1)                    ; => U
(aref #2A((1) (2)) 0)           ; => ERROR (because not enough indexes provided)

또한 제공하는 인덱스는 배열을 만들 때 지정한 차원 범위 안에 있어야 해요. array-in-bounds-p로 확인할 수 있어요:

(array-in-bounds-p #2A((1) (2)) 0 0) ; => T
(array-in-bounds-p #2A((1) (2)) 2 0) ; => NIL

row-major-aref로도 원소에 접근할 수 있는데, 이 함수는 행 우선 순서에서의 원소를 가리키는 정수 하나를 받아요. (행 우선 인덱스는 array-row-major-index로 인덱스들로부터 계산할 수 있어요.)

(array-row-major-index #2A((1 2 3) (4 5 6)) 1 1 ) ; => 4
(row-major-aref #2A((1 2 3) (4 5 6)) 4)           ; => 5

판별

어떤 객체가 배열인지 판별하려면 arrayp를 사용할 수 있어요.

(arrayp #(1 2 3))            ; => T
(arrayp #2((1 2 3) (4 5 6))) ; => T
(arrayp (list 1 2 3))        ; => NIL

배열에 관한 정보

다음 함수들로 배열에 관한 여러 정보를 얻을 수 있어요:

  • array-rank는 배열의 차원 수를 알려줘요. 이 차원 수를 배열의 랭크라고 해요.
  • array-dimensions는 각 차원의 크기를 리스트로 알려줘요.
  • array-dimension은 특정 차원 하나의 크기를 알려줘요.
  • array-total-size는 배열 전체의 원소 개수를 알려줘요.
(let ((array #3A(((0 1) (2 3) (4 5)) 
                 ((6 7) (8 9) (A B)) 
                 ((C D) (E F) (G H))
                 ((I J) (K L) (M N)))))
  (list (array-rank array)
        (array-dimensions array)
        (array-dimension array 1)
        (array-total-size array))) ; => (3 (4 3 2) 2 24)

배열 크기의 한계

Common Lisp 표준은 배열의 최대 크기에 몇 가지 한계를 정해 두고 있어요. 이 한계는 다음과 같은 상수로 정의되어 있어요:

  • array-rank-limit: 배열이 가질 수 있는 최대 차원 수예요. 8 이상으로 정의되어 있어요.
  • array-dimension-limit: 한 차원이 가질 수 있는 최대 크기예요. 1024 이상으로 정의되어 있어요.
  • array-total-size-limit: 배열이 가질 수 있는 최대 원소 개수예요. 1024 이상으로 정의되어 있어요.
GitHub에서 편집 링크가 새 창이나 탭에서 열려요

배열 배우기

연습이 잠겨 있어요

배열 개념을 연습하려면 연습 문제 5개를 더 잠금 해제해요