รับสาย n เป็นหนึ่งในนั้นสตริงย่อยของอื่นหรือไม่


9

สมมติว่าเราจะได้รับคอลเลกชันของสตริงs_1ฉันต้องการทราบว่าสตริงเหล่านี้เป็นสตริงย่อยของสตริงอื่น ๆ ในคอลเลกชันหรือไม่ กล่าวอีกนัยหนึ่งฉันต้องการอัลกอริทึมสำหรับงานต่อไปนี้:nS1,,Sn

อินพุต:S1,,Sn

เอาท์พุท:ดังกล่าวว่าเป็นย่อยของและหรือไม่หากไม่เช่นที่มีอยู่i,jSiSjiji,j

มีอัลกอริทึมที่มีประสิทธิภาพสำหรับสิ่งนี้หรือไม่?

หากเราแทนที่ "substring" ด้วย "คำนำหน้า" จะมีอัลกอริทึมที่มีประสิทธิภาพ (เรียงลำดับสตริงจากนั้นทำการสแกนเชิงเส้นเพื่อเปรียบเทียบสตริงที่อยู่ติดกันการเรียงลำดับจะทำให้แน่ใจว่ามีสตริงย่อยติดกัน) แต่ดูเหมือนจะมีความท้าทายมากขึ้นในการทดสอบว่าสตริงใด ๆ เป็นสตริงย่อยของสตริงอื่น ๆ อัลกอริทึมที่ไร้เดียงสาคือการทำซ้ำในทุกคู่ของแต่ต้องใช้การทดสอบสตริงย่อยมีอัลกอริทึมที่มีประสิทธิภาพมากขึ้นหรือไม่?i,jΘ(n2)

ฉันเดาว่าเราเรียกสิ่งนี้ว่า "การทดสอบสตริงย่อยทุกคู่" หรืออะไรทำนองนั้น

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


คำแนะนำ: อาร์เรย์ต่อท้าย
นามแฝง

จากบันทึกย่อด้านข้างไม่ถูกต้องหากคุณลบสตริงย่อยตามที่คุณพบ มันจะน้อยลง นอกจากนี้คุณควรเรียงตามความยาวเนื่องจากสตริงที่ยาวกว่าไม่สามารถปรากฏในสตริงที่สั้นกว่าได้ อีกครั้งผิดที่นี่ Θ(n2)Θ(n2)
Alexis Wilke

@AlexisWilke,ถูกต้อง: นั่นคือจำนวนการทดสอบสตริงย่อยในกรณีที่แย่ที่สุด (กรณีที่แย่ที่สุดคือสตริงที่ไม่มีสตริงย่อยอื่น ๆ ) การเรียงตามความยาวจะให้คุณเพียงสองปัจจัยเท่านั้นซึ่งจะไม่มีผลต่อ asymptotics Θ(n2)
DW

คำตอบ:


6

คุณสามารถสร้างแผนภูมิต่อท้ายในเวลาเชิงเส้นและตรวจสอบว่ามีโหนดด้านในที่สอดคล้องกับสตริงเต็ม (เวลาคงที่ต่อโหนด)

ในรายละเอียดมากขึ้นเช่นสมมติเราจะได้รับสตริง *s1,,snΣ

  1. สร้าง (ทั่วไป) ต้นไม้ต่อท้ายของกับ pairwise ที่แตกต่างขั้วเครื่องหมาย\s1$1,s2$2,,sn$nn$1,,$nΣ

    การใช้อัลกอริทึมของ Ukkonenสามารถทำได้ในเวลาเชิงเส้น เชิงเส้นในผลรวมของความยาวสตริงทั้งหมด

  2. สมมติว่าคุณติดป้ายใบไม้ด้วยหากพวกเขาเป็นตัวแทนของคำต่อท้ายของ , สำรวจต้นไม้และหาใบเหล่านั้นที่ติดฉลากคือใบไม้ที่สอดคล้องกับเต็ม เงื่อนไข(i,j)si[j..|si|]sin(i,0)

    ใช้เวลาเชิงเส้นในขนาดต้นไม้ซึ่งเป็นเส้นตรงในขนาดอินพุต

  3. ผู้สืบทอดจะออกจากพาเรนต์ของ (ซึ่งมาถึงโดยมีป้ายชื่อ ) แสดงถึงการแข่งขันทั้งหมดจากชุด; สิ่งนี้ตามมาจากค่าคงที่พื้นฐานของต้นไม้ต่อท้าย ค้นหาการแข่งขันใด ๆ โดยลงไปที่ใบไม้ใด ๆ (แต่ )(i,0)$i(i,0)

    ใช้เวลาเชิงเส้นอีกครั้ง

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.