LISP - ลำดับ

ลำดับเป็นชนิดข้อมูลนามธรรมใน LISP เวกเตอร์และรายการเป็นประเภทย่อยที่เป็นรูปธรรมสองประเภทของประเภทข้อมูลนี้ ฟังก์ชันทั้งหมดที่กำหนดไว้ในประเภทข้อมูลลำดับถูกนำไปใช้จริงกับเวกเตอร์และประเภทรายการทั้งหมด

ในส่วนนี้เราจะพูดถึงฟังก์ชันที่ใช้บ่อยที่สุดในลำดับ

ก่อนที่จะเริ่มวิธีต่างๆในการจัดการลำดับ (เช่นเวกเตอร์และรายการ) ให้เราดูรายการฟังก์ชันที่มีทั้งหมด

การสร้างลำดับ

ลำดับการสร้างฟังก์ชันช่วยให้คุณสร้างลำดับประเภทใดก็ได้ ไวยากรณ์สำหรับฟังก์ชันนี้คือ -

make-sequence sqtype sqsize &key :initial-element

สร้างลำดับของประเภทsqtypeและความยาวsqsize

คุณสามารถเลือกที่จะระบุค่าบางอย่างโดยใช้อาร์กิวเมนต์: initial-elementจากนั้นแต่ละองค์ประกอบจะถูกกำหนดค่าเริ่มต้นให้กับค่านี้

ตัวอย่างเช่นสร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์โค้ดต่อไปนี้

(write (make-sequence '(vector float) 
   10 
   :initial-element 1.0))

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

#(1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)

ฟังก์ชันทั่วไปเกี่ยวกับลำดับ

ซีเนียร์ ฟังก์ชั่นและคำอธิบาย
1

elt

อนุญาตให้เข้าถึงแต่ละองค์ประกอบผ่านดัชนีจำนวนเต็ม

2

length

ส่งกลับความยาวของลำดับ

3

subseq

ส่งคืนลำดับย่อยโดยแยกลำดับต่อมาโดยเริ่มต้นที่ดัชนีเฉพาะและต่อไปยังดัชนีสิ้นสุดเฉพาะหรือจุดสิ้นสุดของลำดับ

4

copy-seq

ส่งคืนลำดับที่มีองค์ประกอบเดียวกันกับอาร์กิวเมนต์

5

fill

ใช้เพื่อตั้งค่าองค์ประกอบหลายรายการของลำดับให้เป็นค่าเดียว

6

replace

ต้องใช้สองลำดับและลำดับอาร์กิวเมนต์แรกจะถูกแก้ไขอย่างทำลายล้างโดยการคัดลอกองค์ประกอบที่ต่อเนื่องมาจากลำดับอาร์กิวเมนต์ที่สอง

7

count

ใช้ไอเท็มและลำดับและส่งกลับจำนวนครั้งที่ไอเท็มปรากฏในลำดับ

8

reverse

ส่งคืนลำดับที่มีองค์ประกอบเดียวกันของอาร์กิวเมนต์ แต่อยู่ในลำดับย้อนกลับ

9

nreverse

ส่งคืนลำดับเดียวกันที่มีองค์ประกอบเดียวกันกับลำดับ แต่อยู่ในลำดับย้อนกลับ

10

concatenate

จะสร้างลำดับใหม่ที่มีการต่อกันของลำดับจำนวนเท่าใดก็ได้

11

position

ใช้รายการและลำดับและส่งกลับดัชนีของรายการในลำดับหรือศูนย์

12

find

ต้องใช้ไอเท็มและลำดับ พบรายการในลำดับและส่งคืนหากไม่พบจะส่งคืนศูนย์

13

sort

ใช้ลำดับและเพรดิเคตสองอาร์กิวเมนต์และส่งคืนเวอร์ชันที่เรียงลำดับของลำดับ

14

merge

ใช้เวลาสองลำดับและเพรดิเคตและส่งคืนลำดับที่เกิดจากการรวมสองลำดับตามเพรดิเคต

15

map

ใช้ฟังก์ชัน n-อาร์กิวเมนต์และลำดับ n และส่งกลับลำดับใหม่ที่มีผลลัพธ์ของการใช้ฟังก์ชันกับองค์ประกอบที่ตามมาของลำดับ

16

some

ใช้เพรดิเคตเป็นอาร์กิวเมนต์และวนซ้ำบนลำดับอาร์กิวเมนต์และส่งคืนค่าที่ไม่ใช่ NIL แรกที่ส่งกลับโดยเพรดิเคตหรือส่งกลับเท็จหากเพรดิเคตไม่เป็นที่พอใจ

17

every

ใช้เพรดิเคตเป็นอาร์กิวเมนต์และวนซ้ำตามลำดับอาร์กิวเมนต์มันจะสิ้นสุดโดยส่งคืนเท็จทันทีที่เพรดิเคตล้มเหลว หากเพรดิเคตเป็นที่พอใจเสมอจะส่งคืนจริง

18

notany

ใช้เพรดิเคตเป็นอาร์กิวเมนต์และวนซ้ำตามลำดับอาร์กิวเมนต์และส่งกลับเท็จทันทีที่เพรดิเคตเป็นที่พอใจหรือเป็นจริงหากไม่เป็นเช่นนั้น

19

notevery

ใช้เพรดิเคตเป็นอาร์กิวเมนต์และทำซ้ำตามลำดับอาร์กิวเมนต์และส่งกลับค่าจริงทันทีที่เพรดิเคตล้มเหลวหรือเป็นเท็จหากเพรดิเคตเป็นที่พอใจเสมอ

20

reduce

มันจับคู่กับลำดับเดียวโดยใช้ฟังก์ชันสองอาร์กิวเมนต์ก่อนกับสององค์ประกอบแรกของลำดับจากนั้นไปยังค่าที่ส่งคืนโดยฟังก์ชันและองค์ประกอบที่ตามมาของลำดับ

21

search

ค้นหาลำดับเพื่อค้นหาองค์ประกอบอย่างน้อยหนึ่งรายการที่ตอบสนองการทดสอบบางอย่าง

22

remove

ใช้ไอเท็มและลำดับและส่งคืนลำดับโดยมีอินสแตนซ์ของไอเท็มลบออก

23

delete

นอกจากนี้ยังรับรายการและลำดับและส่งคืนลำดับของชนิดเดียวกันกับลำดับอาร์กิวเมนต์ที่มีองค์ประกอบเหมือนกันยกเว้นรายการ

24

substitute

ใช้รายการใหม่รายการที่มีอยู่และลำดับและส่งคืนลำดับที่มีอินสแตนซ์ของรายการที่มีอยู่แทนที่ด้วยรายการใหม่

25

nsubstitute

ใช้รายการใหม่รายการที่มีอยู่และลำดับและส่งคืนลำดับเดียวกันโดยมีอินสแตนซ์ของรายการที่มีอยู่แทนที่ด้วยรายการใหม่

26

mismatch

ใช้เวลาสองลำดับและส่งกลับดัชนีของคู่แรกขององค์ประกอบที่ไม่ตรงกัน

อาร์กิวเมนต์คำสำคัญของฟังก์ชันลำดับมาตรฐาน

การโต้เถียง ความหมาย ค่าเริ่มต้น
:ทดสอบ เป็นฟังก์ชันสองอาร์กิวเมนต์ที่ใช้ในการเปรียบเทียบรายการ (หรือค่าที่แยกโดย: ฟังก์ชันคีย์) กับองค์ประกอบ EQL
:สำคัญ ฟังก์ชันอาร์กิวเมนต์เดียวเพื่อดึงค่าคีย์จากองค์ประกอบลำดับจริง NIL หมายถึงใช้องค์ประกอบตามที่เป็นอยู่ ไม่มี
: เริ่มต้น ดัชนีเริ่มต้น (รวม) ของลำดับต่อมา 0
: จบ สิ้นสุดดัชนี (ไม่รวม) ของลำดับต่อมา NIL ระบุจุดสิ้นสุดของลำดับ ไม่มี
: จากปลาย ถ้าเป็นจริงลำดับจะถูกย้อนกลับตามลำดับตั้งแต่ต้นจนจบ ไม่มี
:นับ ตัวเลขระบุจำนวนองค์ประกอบที่จะลบหรือแทนที่หรือ NIL เพื่อระบุทั้งหมด (ลบและแทนที่เท่านั้น) ไม่มี

เราเพิ่งพูดถึงฟังก์ชันและคีย์เวิร์ดต่างๆที่ใช้เป็นอาร์กิวเมนต์ในฟังก์ชันเหล่านี้ที่ทำงานบนลำดับ ในส่วนถัดไปเราจะดูวิธีใช้ฟังก์ชันเหล่านี้โดยใช้ตัวอย่าง

การหาความยาวและองค์ประกอบ

length ฟังก์ชันจะส่งกลับความยาวของลำดับและ elt ฟังก์ชันช่วยให้คุณเข้าถึงแต่ละองค์ประกอบโดยใช้ดัชนีจำนวนเต็ม

ตัวอย่าง

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(setq x (vector 'a 'b 'c 'd 'e))
(write (length x))
(terpri)
(write (elt x 3))

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

5
D

การปรับเปลี่ยนลำดับ

ฟังก์ชันลำดับบางฟังก์ชันช่วยให้สามารถวนซ้ำตามลำดับและดำเนินการบางอย่างเช่นค้นหาลบนับหรือกรององค์ประกอบเฉพาะโดยไม่ต้องเขียนลูปที่ชัดเจน

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -

ตัวอย่าง 1

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(write (count 7 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (remove 5 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (delete 5 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (substitute 10 7 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (find 7 '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (position 5 '(1 5 6 7 8 9 2 7 3 4 5)))

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

2
(1 6 7 8 9 2 7 3 4)
(1 6 7 8 9 2 7 3 4)
(1 5 6 10 8 9 2 10 3 4 5)
7
1

ตัวอย่าง 2

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(write (delete-if #'oddp '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (delete-if #'evenp '(1 5 6 7 8 9 2 7 3 4 5)))
(terpri)
(write (remove-if #'evenp '(1 5 6 7 8 9 2 7 3 4 5) :count 1 :from-end t))
(terpri)
(setq x (vector 'a 'b 'c 'd 'e 'f 'g))
(fill x 'p :start 1 :end 4)
(write x)

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

(6 8 2 4)
(1 5 7 9 7 3 5)
(1 5 6 7 8 9 2 7 3 5)
#(A P P P E F G)

ลำดับการเรียงลำดับและการผสาน

ฟังก์ชันการเรียงลำดับใช้ลำดับและเพรดิเคตสองอาร์กิวเมนต์และส่งคืนเวอร์ชันที่เรียงลำดับของลำดับ

ตัวอย่าง 1

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(write (sort '(2 4 7 3 9 1 5 4 6 3 8) #'<))
(terpri)
(write (sort '(2 4 7 3 9 1 5 4 6 3 8) #'>))
(terpri)

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

(1 2 3 3 4 4 5 6 7 8 9)
(9 8 7 6 5 4 4 3 3 2 1)

ตัวอย่าง 2

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(write (merge 'vector #(1 3 5) #(2 4 6) #'<))
(terpri)
(write (merge 'list #(1 3 5) #(2 4 6) #'<))
(terpri)

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

#(1 2 3 4 5 6)
(1 2 3 4 5 6)

ลำดับคำทำนาย

ฟังก์ชั่นทุก ๆ ตัวบางตัวโน้ตและโน้ตทุกตัวเรียกว่าเพรดิเคตลำดับ

ฟังก์ชันเหล่านี้วนซ้ำตามลำดับและทดสอบเพรดิเคตบูลีน

ฟังก์ชันทั้งหมดนี้ใช้เพรดิเคตเป็นอาร์กิวเมนต์แรกและอาร์กิวเมนต์ที่เหลือคือลำดับ

ตัวอย่าง

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(write (every #'evenp #(2 4 6 8 10)))
(terpri)
(write (some #'evenp #(2 4 6 8 10 13 14)))
(terpri)
(write (every #'evenp #(2 4 6 8 10 13 14)))
(terpri)
(write (notany #'evenp #(2 4 6 8 10)))
(terpri)
(write (notevery #'evenp #(2 4 6 8 10 13 14)))
(terpri)

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

T
T
NIL
NIL
T

ลำดับการแม็ป

เราได้กล่าวถึงฟังก์ชันการทำแผนที่แล้ว ในทำนองเดียวกันmap ฟังก์ชันช่วยให้คุณสามารถใช้ฟังก์ชันกับองค์ประกอบที่ตามมาของลำดับอย่างน้อยหนึ่งลำดับ

map ฟังก์ชันรับฟังก์ชัน n-อาร์กิวเมนต์และลำดับ n และส่งกลับลำดับใหม่หลังจากใช้ฟังก์ชันกับองค์ประกอบที่ตามมาของลำดับ

ตัวอย่าง

สร้างไฟล์ซอร์สโค้ดใหม่ชื่อ main.lisp และพิมพ์รหัสต่อไปนี้

(write (map 'vector #'* #(2 3 4 5) #(3 5 4 8)))

เมื่อคุณรันโค้ดจะส่งคืนผลลัพธ์ต่อไปนี้ -

#(6 15 16 40)