Ма

Масиви у Common Lisp

6 вправ

Про концепцію Масиви

У Common Lisp, як і в інших мовах, масив складається з елементів, доступ до яких отримують за цілочисловими індексами. Типи елементів можуть бути різнорідними. Масив може бути багатовимірним (а не лише одновимірним).

Створення

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; відлік індексів починається з нуля. Кількість наданих індексів має збігатися з рангом масиву.

(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 вправ, щоб практикувати концепцію Масиви