Ar

Arrays em Common Lisp

6 exercícios

Sobre Arrays

Em Common Lisp, tal como noutras linguagens, um array, também chamado vetor, é um conjunto de elementos acedidos através de índices inteiros. Os tipos dos elementos podem ser heterogéneos. O array pode ser multidimensional (não apenas unidimensional).

Criação

make-array permite criar arrays. Tem muitas opções, mas as suas formas mais simples permitem criar arrays N-dimensionais com todos os elementos inicializados a um único valor, ou com o array inicializado com os valores de outra sequência (como uma lista). O primeiro argumento é uma lista com o tamanho de cada dimensão.

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

(Repara como os arrays N-dimensionais são impressos com o número de dimensões.)

Os arrays também podem ser criados com o mesmo formato em que são impressos:

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

Acesso a elementos

Para aceder aos elementos de um vetor, usa aref; os índices começam em zero. O número de índices fornecidos tem de corresponder ao número de dimensões do array.

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

Além disso, os índices fornecidos têm de estar dentro dos limites das dimensões definidas quando o array foi criado. Isto pode ser verificado com array-in-bounds-p:

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

Também se pode aceder a um elemento com row-major-aref, que recebe um único inteiro que especifica o elemento na ordem por linhas. (O índice na ordem por linhas pode ser calculado a partir dos índices com 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

Predicado

Para determinar se um objeto é um array, podes usar arrayp.

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

Consultas sobre arrays

É possível obter várias informações sobre um array com as seguintes funções:

  • array-rank para obter o número de dimensões do array (a que se chama a ordem do array).
  • array-dimensions para obter uma lista com os tamanhos das dimensões do array.
  • array-dimension para obter o tamanho de uma das dimensões.
  • array-total-size para obter o número total de elementos do array.
(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)

Limites no tamanho dos arrays

A norma Common Lisp define alguns limites para o tamanho máximo dos arrays. Estes limites estão disponíveis em algumas constantes definidas:

  • array-rank-limit: o número máximo permitido de dimensões de um array (definido como não inferior a 8).
  • array-dimension-limit: o tamanho máximo de uma dimensão (definido como não inferior a 1024).
  • array-total-size-limit: o número máximo de elementos de qualquer array (definido como não inferior a 1024).
Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Arrays

A prática está bloqueada

Desbloqueia mais 5 exercícios para praticares Arrays