มีจำนวนองค์ประกอบในข้อมูลของคุณ:
say elems <1 1 0 2 0 2 1 2 2 2 4 4 3 3>; # 14
grep
บล็อกของคุณใช้สององค์ประกอบในแต่ละครั้ง:
{$^a eq $^b}
ดังนั้นหากคุณเพิ่มหรือลบองค์ประกอบคุณจะได้รับข้อผิดพลาดที่คุณได้รับเมื่อมีการเรียกใช้บล็อกในองค์ประกอบเดียวที่เหลือในตอนท้าย
มีหลายวิธีในการแก้ปัญหาของคุณ
แต่คุณยังถามเกี่ยวกับตัวเลือกในการอนุญาตให้ทับซ้อนกันเช่นคุณได้รับสอง(2 2)
รายการย่อยเมื่อ2 2 2
พบลำดับ และในหลอดเลือดดำที่คล้ายกันคุณอาจต้องการเห็นการแข่งขันสองรายการไม่ใช่ศูนย์โดยมีการป้อนข้อมูลเช่น:
<1 2 2 3 3 4>
ดังนั้นฉันจะมุ่งเน้นการแก้ไขปัญหาที่จัดการกับปัญหาเหล่านั้นด้วย
แม้จะมีการ จำกัด พื้นที่โซลูชันเพื่อจัดการกับปัญหาพิเศษ แต่ยังมีอีกหลายวิธีในการแสดงวิธีแก้ปัญหา
วิธีหนึ่งที่เพิ่มโค้ดอีกเล็กน้อยเข้าท้ายของคุณ:
my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s .rotor( 2 => -1 ) .flat
.rotor
วิธีการแปลงรายการลงในรายการย่อยรายการ-แต่ละความยาวเดียวกัน ยกตัวอย่างเช่นการแสดงsay <1 2 3 4> .rotor: 2
((1 2) (3 4))
หากอาร์กิวเมนต์ความยาวเป็นคู่คีย์จะมีความยาวและค่าจะเป็นออฟเซ็ตสำหรับการเริ่มต้นคู่ถัดไป หากออฟเซตเป็นลบคุณจะได้รับรายการย่อยทับกัน ดังนั้นการแสดงsay <1 2 3 4> .rotor: 2 => -1
((1 2) (2 3) (3 4))
.flat
วิธีการ "แบน" invocant ของมัน ยกตัวอย่างเช่นการแสดงsay ((1,2),(2,3),(3,4)) .flat
(1 2 2 3 3 4)
วิธีที่ง่ายกว่าในการเขียนวิธีการแก้ปัญหาข้างต้นคือการละเว้นflat
และการใช้.[0]
และ.[1]
เพื่อจัดทำดัชนีในรายการย่อยที่ส่งคืนโดยrotor
:
say @s .rotor( 2 => -1 ) .grep: { .[0] eq .[1] }
ดูความคิดเห็นของ Elizabeth Mattijsen สำหรับรูปแบบอื่นที่ทำให้ขนาดรายการย่อยเป็นแบบทั่วไป
หากคุณต้องการรูปแบบการเข้ารหัสทั่วไปมากขึ้นคุณอาจจะเขียนสิ่งที่ชอบ:
say @s .pairs .map: { .value xx 2 if .key < @s - 1 and [eq] @s[.key,.key+1] }
.pairs
วิธีในรายการกลับรายการของคู่แต่ละคู่ที่สอดคล้องกับแต่ละองค์ประกอบในรายการ invocant ของตน .key
ของแต่ละคู่เป็นดัชนีขององค์ประกอบในรายการ invocant นั้น .value
คุ้มค่าขององค์ประกอบ
.value xx 2
สามารถเขียน.value, .value
ได้ (ดูxx
.)
@s - 1
คือจำนวนขององค์ประกอบใน@s
ลบ 1
[eq]
ใน[eq] list
เป็นลดลง
หากคุณต้องการการจับคู่รูปแบบข้อความเพื่อตัดสินใจว่าองค์ประกอบใดที่มีองค์ประกอบเท่ากันอย่างต่อเนื่องคุณอาจแปลงรายการอินพุตให้เป็นสตริงให้จับคู่กับคำวิเศษณ์จับคู่ที่สร้างรายการการแข่งขันจากนั้นแมปจากรายการผลลัพธ์ของการจับคู่ที่คุณต้องการ ผลลัพธ์. เพื่อจับคู่กับการซ้อนทับ (เช่น2 2 2
ผลลัพธ์ที่((2 2) (2 2))
ใช้อยู่:ov
:
say @s .Str .match( / (.) ' ' $0 /, :ov ) .map: { .[0].Str xx 2 }
2 2 2 2
มันจะพิมพ์ 3(2 2)
วินาทีซึ่งเป็นไปตามที่คาดไว้ ไม่เคยได้ยินเกี่ยวกับวิธีการที่rotor
ฉันเริ่มต้นด้วยsquish
วิธีการและตรวจสอบว่ามันมีคุณสมบัติหรือข้อโต้แย้งเช่น@s.squish(:length 2, :multiple_instances yes)
แต่มันไม่ได้มีคุณสมบัติดังกล่าวและมันก็ไม่เหมาะสำหรับงาน เมื่อเทียบกับsquish
,rotor
ดูเหมือนว่าค่อนข้างพอดี จริงๆแล้วมันอาจจะเหมาะสมที่สุดสำหรับการทำงานประเภทนี้