หากคุณไม่มีปริญญา CS (วิทยาการคอมพิวเตอร์) คุณอาจรู้สึกว่าคุณกำลังพลาดอะไรบางอย่าง...
หรือคุณอาจรู้สึกว่า CS เป็นนามธรรมเกินกว่าจะเป็นประโยชน์…
หรือว่ารูบี้ทำงานหนักเพื่อคุณอยู่แล้ว…
ไม่ว่าทางใด…
การทำความเข้าใจพื้นฐานของโครงสร้างข้อมูล เช่น แฮช สแต็ค และคิวจะเป็นประโยชน์
ในโพสต์นี้ :
คุณจะค้นพบวิธีใช้สแต็คใน Ruby
แนวคิดด้านวิทยาการคอมพิวเตอร์ที่นำไปใช้ได้จริงซึ่งคุณสามารถเริ่มนำไปปฏิบัติได้ทันที!
ทำความเข้าใจเรื่อง Stacks ใน Ruby
สแต็คใน Ruby คืออะไร
สแต็กคือโครงสร้างข้อมูลที่คุณสามารถใช้เป็นรายการ "สิ่งที่ต้องทำ" ได้ คุณเก็บเอาองค์ประกอบจากสแต็กและประมวลผลจนกว่าสแต็กจะว่างเปล่า
นี่คือการแสดงภาพ
ดัน 5 ลงในกองว่าง :
5
ดัน 3 ลงในกอง :
3
5
ดัน 9 เข้าไปในกอง :
9
3
5
หยิบหนึ่งรายการจากกอง :
3
5
สิ่งสำคัญที่ควรสังเกตคือมีการเพิ่มรายการใหม่ลงใน ด้านบนของสแต็ก . ในรูปแบบ "เข้าก่อนออกก่อน" (LIFO) หมายความว่าเมื่อคุณเอา (ป๊อป) ไอเท็มจากสแต็ค มันจะเป็นไอเท็มสุดท้ายที่ถูกผลักเข้าไป
อีกวิธีในการแสดงภาพวิธีการทำงานคือการคิดถึงกองจาน หากคุณใส่แผ่นหนึ่งทับอีกแผ่นหนึ่ง คุณจะไม่สามารถถอดแผ่นด้านล่างออกโดยไม่นำแผ่นด้านบนออกก่อน
นั่นคือทั้งหมดที่คุณทำกับสแต็ก ดันสิ่งต่าง ๆ ขึ้นไปด้านบนหรือดึงสิ่งต่าง ๆ ออกมา มี ไม่มีการจัดทำดัชนี .
มาดูตัวอย่างโค้ดบางส่วนเกี่ยวกับวิธีการใช้งาน
วิธีการแผ่อาร์เรย์โดยใช้สแต็ก
ตัวอย่างคลาสสิกของสแต็คคือการใช้สแต็กเพื่อทำให้อาร์เรย์เรียบ กล่าวคือ แปลงอาร์เรย์หลายมิติเป็นอาร์เรย์หนึ่งมิติ
นี่คือตัวอย่าง :
arr = [1,2,3,[4,5],6] arr.flatten
ใน Ruby เรามีวิธีที่ทำให้เรียบซึ่งทำเช่นนี้เพื่อคุณ แต่ถ้าคุณไม่มีวิธีนี้ล่ะ และวิธีนี้ทำงานอย่างไร
นี่คือที่มาของสแต็ก!
Ruby ใช้ วิธีพุช &ป๊อป ดังนั้นเราจึงสามารถจัดการกับอาร์เรย์เหมือนสแต็กได้
หมายเหตุ:ทั้ง
กด
&<<รหัส> เป็นวิธีเดียวกัน ฉันจะใช้
<<
ในตัวอย่างโค้ดของฉัน
แนวคิดคือการตรวจสอบทุกองค์ประกอบและตรวจสอบว่าเป็นอาร์เรย์หรืออย่างอื่น ถ้าเป็นอาร์เรย์ เราจะ พุช
องค์ประกอบภายในอาร์เรย์นี้กลับเข้าสู่สแต็ก
สิ่งที่เกิดขึ้นคือเราลบเลเยอร์อาร์เรย์ (เช่น หัวหอม) ออกไปเรื่อยๆ จนกว่าจะไม่เหลือ สิ่งนี้จะทำให้เรามีอาร์เรย์ที่แบนราบ
นี่คือรหัส :
arr = [1,2,3,[4,5],6] flat = [] arr.each do |thing| if thing.is_a? Array thing.each { |i| arr << i } else flat << thing end end p flat # [1, 2, 3, 6, 4, 5]
คุณจะสังเกตเห็นว่าไม่มี ป๊อป
เรียกเมธอดในโค้ดนี้
นี่เป็นเพราะฉันปล่อยให้ แต่ละ
ทำงานหนักเพื่อนำไอเท็มจากสแต็ก &ป้อนให้กับอัลกอริทึมของฉัน สังเกตด้วยว่าลำดับขององค์ประกอบไม่ได้รับการดูแลเมื่อทำสิ่งนี้ด้วยวิธีนี้
รุ่นอื่นใช้ จนถึง
&ว่างเปล่า?
:
until arr.empty? thing = arr.pop if thing.is_a? Array thing.each { |i| arr << i } else flat << thing end end p flat # [6, 5, 4, 3, 2, 1]
เนื่องจากเราใช้ pop
ตอนนี้แทนที่จะปล่อยให้ แต่ละ
ทำตามนั้น เราจะได้อาร์เรย์แบบแบนในลำดับที่ถูกต้อง... แต่ในทางกลับกัน
เผยให้เห็นคุณสมบัติที่น่าสนใจของสแต็ค :
รายการสิ่งของที่คุณใส่เข้าไปก็จะกลับมาในลำดับเดิมแต่กลับกัน
เคล็ดลับ:
Array#flatten
เมธอดรับอาร์กิวเมนต์ ซึ่งให้คุณกำหนดจำนวนเลเยอร์ที่คุณต้องการลบ (โดยค่าเริ่มต้นทั้งหมด)
การแก้ปัญหาวงเล็บสมดุล
นี่เป็นอีกตัวอย่างหนึ่ง &ไม่มีวิธี Ruby ที่เทียบเท่าในการทำเช่นนี้สำหรับคุณ!
ยังเป็นอีกปัญหาคลาสสิกในวิทยาการคอมพิวเตอร์...
ชื่อ:
จับคู่วงเล็บสมดุล
แนวคิดคือคุณได้รับสตริง &คุณต้องตรวจสอบว่าวงเล็บถูกต้องหรือไม่
ตัวอย่างเช่น สมมติว่าคุณกำลังเขียนโปรแกรมประเมินผลคณิตศาสตร์ คุณต้องการให้แน่ใจว่าข้อมูลที่ป้อนนั้นถูกต้องก่อนดำเนินการ
ตัวอย่าง (ข้อมูลที่ถูกต้อง):
input = "1 + (4 + 6) * 2"
ตัวอย่าง (อินพุตไม่ถูกต้อง):
input = "1 + (4 + 6 * 2"
คุณสามารถใช้สแต็กเพื่อติดตามวงเล็บที่คุณพบในอินพุต จากนั้นเมื่อคุณพบวงเล็บใหม่ ให้ตรวจสอบด้านบนของสแต็กเพื่อให้แน่ใจว่าตรงกับวงเล็บปิด
หากไม่มีข้อมูลที่ตรงกันแสดงว่าคุณป้อนข้อมูลไม่ถูกต้อง
ตัวอย่าง :
PARENS = { "(" => ")", "{" => "}", "[" => "]" } OPENING_PARENS = PARENS.keys CLOSING_PARENS = PARENS.values def valid_parentheses(string) stack = [] string.each_char do |ch| if OPENING_PARENS.include?(ch) stack << ch elsif CLOSING_PARENS.include?(ch) ch == PARENS[stack.last] ? stack.pop : (return false) end end stack.empty? end p valid_parentheses("(){}[]") # true p valid_parentheses("[(])") # false
อีกสิ่งหนึ่งที่คุณจะสังเกตได้คือฉันจบ valid_parentheses
. นี้แล้ว เมธอดด้วย stack.empty?
. เพื่อให้แน่ใจว่าเราจะไม่ลงท้ายด้วยวงเล็บเปิด
หากวงเล็บทั้งหมดปิดอย่างถูกต้อง สแต็กก็ควรว่างเปล่า 🙂
ตัวอย่างที่ 3 (ทิศทาง)
อีกหนึ่งตัวอย่างเพื่อให้แน่ใจว่าคุณเข้าใจวิธีการใช้สิ่งนี้
ในกรณีนี้ เราได้รับชุดเส้นทาง &เราได้รับแจ้งว่าเราจำเป็นต้องปรับให้เหมาะสมเพื่อประหยัดเวลานักเดินทางของเรา
นี่คือชุดตัวอย่าง:
["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
คุณจะสังเกตได้ว่าถ้าคุณไปทางเหนือแล้วลงใต้ คุณจะไปอยู่ที่เดียวกัน (สมมติว่าทั้งสองทิศทางมีระยะทางเท่ากัน) นั่นคือสิ่งที่เราต้องเพิ่มประสิทธิภาพและเราสามารถทำได้โดยใช้สแต็ก
ตัวอย่าง :
input = ["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] directions = [] opposites = { "NORTH" => "SOUTH", "SOUTH" => "NORTH", "EAST" => "WEST", "WEST" => "EAST" } input.each do |dir| opposites[dir] == directions.last ? directions.pop : directions << dir end p directions
บทสรุป
ฉันหวังว่าคุณจะได้เรียนรู้สิ่งใหม่ๆ และคุณเริ่มมองหาวิธีใช้สแต็คเพื่อแก้ปัญหาการเขียนโปรแกรม
อย่าลืม แชร์โพสต์นี้ เพื่อให้คนอ่านมากขึ้น!