آر

آرایه در 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: حداکثر تعداد مجاز ابعاد یک آرایه (تعریف‌شده به‌گونه‌ای که کمتر از ۸ نباشد).
  • array-dimension-limit: حداکثر اندازه‌ی هر یک از ابعاد (تعریف‌شده به‌گونه‌ای که کمتر از ۱۰۲۴ نباشد).
  • array-total-size-limit: حداکثر تعداد عناصر هر آرایه (تعریف‌شده به‌گونه‌ای که کمتر از ۱۰۲۴ نباشد).
ویرایش از طریق GitHub این پیوند در پنجره یا زبانه‌ی جدیدی باز می‌شود

آرایه را یاد بگیرید

تمرین کردن قفل شده است

برای تمرین آرایه قفل 5 تمرین دیگر را باز کنید