ال

المصفوفات في 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 تمارين إضافية لممارسة المصفوفات