เวกเตอร์
ใน Scheme เวกเตอร์เป็นอีกหนึ่งโครงสร้างข้อมูลพื้นฐานที่ใช้ในการจัดกลุ่มค่า ต่างจากรายการตรงที่เวกเตอร์จะมีขนาดคงที่ คอลเลกชันขององค์ประกอบที่จัดทำดัชนีแล้ว ช่วยให้เข้าถึงและอัปเดตแบบสุ่มได้รวดเร็วยิ่งขึ้น แต่ละองค์ประกอบในเวกเตอร์สามารถเป็นประเภทใดก็ได้ รวมถึงเวกเตอร์อื่นด้วย เวกเตอร์แสดงโดยใช้ # ตามด้วยวงเล็บ #(1 2 3)
แม้ว่าเวกเตอร์และรายการอาจดูคล้ายกัน แต่ก็มีจุดประสงค์ที่แตกต่างกันในการเขียนโปรแกรม Scheme:
รายการมักใช้สำหรับการดำเนินการแบบเรียกซ้ำและโครงสร้างไดนามิก เนื่องจากการใช้งานโหนดที่เชื่อมโยงช่วยให้การจัดการจุดเริ่มต้นและการสำรวจเส้นทางมีประสิทธิภาพผ่านการสลายตัวแบบเรียกซ้ำ
ในทางกลับกัน เวกเตอร์ ได้รับการปรับให้เหมาะสมสำหรับสถานการณ์ที่จำเป็นต้องมีการเข้าถึงองค์ประกอบแบบสุ่มหรือการอัพเดตที่ดัชนีเฉพาะ ทำให้เหมาะสมมากขึ้นสำหรับกรณีการใช้งาน เช่น ตารางการค้นหา การกำหนดค่าขนาดคงที่ หรือการดำเนินการจัดทำดัชนีที่มีความสำคัญต่อประสิทธิภาพ
โดยพื้นฐานแล้ว รายการต่างๆ เป็นตัวเลือกที่เป็นธรรมชาติสำหรับอัลกอริธึมแบบเรียกซ้ำและข้อมูลที่มีขนาดไดนามิก ในขณะที่เวกเตอร์จะโดดเด่นเมื่อรูปแบบการเข้าถึงที่มีขนาดคงที่หรือจัดทำดัชนีเป็นสิ่งสำคัญยิ่ง
เวกเตอร์อย่างง่าย
(vector 1 2 3)- สร้างเวกเตอร์ของสามองค์ประกอบ:
1,2และ3
ผลลัพธ์: #(1 2 3)
การเข้าถึงองค์ประกอบเวกเตอร์
เข้าถึงองค์ประกอบในเวกเตอร์ได้โดยใช้ขั้นตอน vector-ref โดยจะดึงข้อมูลองค์ประกอบจากดัชนีที่ระบุ (เริ่มจาก 0)
(define my-vector (vector 1 2 3))
(vector-ref my-vector 0) ; Retrieves the element at index 0
(vector-ref my-vector 1) ; Retrieves the element at index 1การวนซ้ำ: การประมวลผลแต่ละองค์ประกอบในเวกเตอร์
คุณสามารถวนซ้ำผ่านเวกเตอร์โดยใช้การวนซ้ำหรือการเรียกซ้ำ Scheme จัดเตรียม vector-length เพื่อกำหนดขนาดของเวกเตอร์ ต่อไปนี้เป็นวิธีง่ายๆ ในการพิมพ์ทุกองค์ประกอบในเวกเตอร์:
(define (print-elements vec)
(let loop ((i 0))
(if (< i (vector-length vec))
(begin
(lumi-message (number->string (vector-ref vec i))) ; Print the element
(loop (+ i 1))) ; Process the next index
(lumi-message "done")))) ; End loop- กรณีฐาน: หากดัชนี
iถึงความยาวของเวกเตอร์ ให้หยุดการวนซ้ำ - กรณีแบบเรียกซ้ำ: พิมพ์องค์ประกอบที่ดัชนี
iจากนั้นเพิ่มค่าi
ตัวอย่างการใช้งาน
(print-elements (vector 1 2 3))ผลลัพธ์:
"1""2""3"
ผลลัพธ์: “เสร็จสิ้น”
เวกเตอร์ผสม
เวกเตอร์สามารถรวมองค์ประกอบประเภทต่างๆ ได้ รวมถึงสตริง บูลีน ตัวเลข เวกเตอร์อื่นๆ หรือแม้แต่ผลลัพธ์ของนิพจน์:
(vector 42 "hello" #t (vector 1 2) (+ 3 4))สิ่งนี้จะสร้างเวกเตอร์ด้วย:
- ตัวเลข (
42) - สตริง (
"hello") - บูลีน (
#t) - เวกเตอร์อีกอัน (
#(1 2)) - ผลลัพธ์ของนิพจน์ (
(+ 3 4)ซึ่งประเมินเป็น7)
ผลลัพธ์: #(42 "hello" #t #(1 2) 7)
การสร้างเวกเตอร์
เวกเตอร์ถูกสร้างขึ้นโดยใช้ vector หรือโดยใช้ make-vector เพื่อสร้างเวกเตอร์ที่มีขนาดคงที่พร้อมค่าเริ่มต้น
(make-vector 5 0)สร้างเวกเตอร์ขนาด 5 โดยมีองค์ประกอบทั้งหมดเริ่มต้นเป็น 0
ผลลัพธ์: #(0 0 0 0 0)
การอัปเดตเวกเตอร์
ขั้นตอน vector-set! จะอัปเดตองค์ประกอบในเวกเตอร์ที่ดัชนีที่ระบุ
(define my-vector (vector 1 2 3))
(vector-set! my-vector 1 42) ; Sets the second element to 42
my-vectorผลลัพธ์: #(1 42 3)
กำลังตรวจสอบเวกเตอร์
กระบวนการ vector? จะตรวจสอบว่าค่าที่กำหนดเป็นเวกเตอร์หรือไม่
(vector? (vector 1 2 3)) ; Checks if #(1 2 3) is a vector
(vector? 42) ; Checks if 42 is a vectorผลลัพธ์:
(vector? (vector 1 2 3))ส่งกลับ#t(จริง)(vector? 42)ส่งคืน#f(เท็จ)
เวกเตอร์และพฤติกรรมการอ้างอิงใน Scheme เวกเตอร์ไม่แน่นอนและส่งผ่านโดยการอ้างอิง ซึ่งหมายความว่าเมื่อคุณส่งเวกเตอร์ไปยังฟังก์ชัน ฟังก์ชันจะสามารถแก้ไขเวกเตอร์ดั้งเดิมได้โดยตรง การเปลี่ยนแปลงใดๆ ที่ทำกับเวกเตอร์ภายในฟังก์ชันจะมีผลภายนอกฟังก์ชันด้วย ลักษณะการทำงานนี้มีประโยชน์สำหรับการแบ่งปันและอัปเดตข้อมูลข้ามฟังก์ชันต่างๆ ได้อย่างมีประสิทธิภาพ แต่ยังต้องใช้ความระมัดระวังเพื่อหลีกเลี่ยงผลข้างเคียงที่ไม่ได้ตั้งใจ
ตัวอย่าง: การแก้ไขเวกเตอร์ในฟังก์ชัน
นี่คือตัวอย่างที่แสดงให้เห็นว่าเวกเตอร์ถูกส่งผ่านโดยการอ้างอิงและแก้ไขอย่างไร:
(define (modify-vector vec index new-value)
(vector-set! vec index new-value)) ; Updates the vector at the specified index
(define my-vector (vector 10 20 30))
(modify-vector my-vector 1 99) ; Modifies the second element to 99
my-vector ; The original vector is now updatedผลลัพธ์: #(10 99 30)
คำอธิบายทีละขั้นตอน
- สร้างเวกเตอร์:
my-vectorเริ่มต้นได้ด้วยค่า10,20และ30 - ส่งผ่านไปยังฟังก์ชัน:
my-vectorถูกส่งผ่านไปยังmodify-vectorพร้อมด้วยดัชนีและค่าใหม่ที่จะอัปเดต - แก้ไขในฟังก์ชัน: ขั้นตอน
vector-set!จะอัปเดตค่าที่ดัชนีที่ระบุโดยตรงในเวกเตอร์ดั้งเดิม - สะท้อนการเปลี่ยนแปลง: เนื่องจากเวกเตอร์ถูกส่งผ่านโดยการอ้างอิง การเปลี่ยนแปลงที่ทำภายในฟังก์ชันจึงสะท้อนให้เห็นในเวกเตอร์ดั้งเดิม
ผลกระทบของการอ้างอิงแบบผ่าน
- ประสิทธิภาพ: การส่งผ่านเวกเตอร์โดยการอ้างอิงมีประสิทธิภาพเนื่องจากจะหลีกเลี่ยงการคัดลอกโครงสร้างขนาดใหญ่
- ผลข้างเคียง: โปรดใช้ความระมัดระวังเมื่อแชร์เวกเตอร์ข้ามฟังก์ชันต่างๆ เพื่อหลีกเลี่ยงการแก้ไขข้อมูลที่แชร์โดยไม่ได้ตั้งใจ
การดำเนินการกับเวกเตอร์
Scheme มีขั้นตอนในตัวหลายอย่างสำหรับการทำงานกับเวกเตอร์ รวมไปถึง:
vector-length: ส่งกลับจำนวนองค์ประกอบในเวกเตอร์vector->list: แปลงเวกเตอร์ให้เป็นรายการlist->vector: แปลงรายการให้เป็นเวกเตอร์
(vector-length (vector 1 2 3)) ; Returns 3
(vector->list (vector 1 2 3)) ; Converts vector to list: (1 2 3)
(list->vector (list 1 2 3)) ; Converts list to vector: #(1 2 3)ผลลัพธ์:
(vector-length (vector 1 2 3))กลับมา3(vector->list (vector 1 2 3))กลับมา(1 2 3)(list->vector (list 1 2 3))กลับมา#(1 2 3)
เวกเตอร์ที่ซ้อนกัน
เวกเตอร์ใน Scheme สามารถมีเวกเตอร์อื่นเป็นองค์ประกอบ ทำให้เกิดโครงสร้างที่ซ้อนกัน
(define nested-vector (vector (vector 1 2) (vector 3 4) (vector 5)))สร้างเวกเตอร์ที่มีองค์ประกอบ 3 ส่วน ซึ่งแต่ละองค์ประกอบก็เป็นเวกเตอร์ในตัวมันเอง
ผลลัพธ์: #(#(1 2) #(3 4) #(5))
การเข้าถึงข้อมูลที่ซ้อนกัน
หากต้องการเข้าถึงองค์ประกอบภายในเวกเตอร์ที่ซ้อนกัน ให้ใช้ vector-ref หลายครั้งเพื่อเลื่อนดูโครงสร้าง
ตัวอย่าง: การเข้าถึงองค์ประกอบ
(vector-ref nested-vector 0) ; Retrieves the first element: #(1 2)
(vector-ref (vector-ref nested-vector 0) 1) ; Retrieves the second element of the first vector: 2สรุป
- เวกเตอร์ ใน Scheme มีขนาดคงที่ โครงสร้างข้อมูลที่จัดทำดัชนีไว้
- ใช้
vectorเพื่อสร้างเวกเตอร์vector-refเพื่อเข้าถึงองค์ประกอบ และvector-set!เพื่ออัปเดตองค์ประกอบ - ขั้นตอนในตัว เช่น
vector-length,vector->listและlist->vectorช่วยให้การดำเนินงานมีความยืดหยุ่น - เวกเตอร์ที่ซ้อนกันทำให้เกิดโครงสร้างข้อมูลที่ซับซ้อนและเป็นลำดับชั้น