มีโครงสร้างข้อมูล 'สตริงสแต็ค' ที่สนับสนุนการดำเนินงานของสตริงเหล่านี้หรือไม่


28

ฉันกำลังมองหาโครงสร้างข้อมูลที่เก็บชุดสตริงไว้ในชุดอักขระสามารถทำการดำเนินการต่อไปนี้ได้ เราแสดงว่าเป็นโครงสร้างข้อมูลการจัดเก็บชุดของสตริงSD ( S ) SΣD(S)S

  • Add-Prefix-Setบน : กำหนดชุดของ (อาจว่างเปล่า) สตริงซึ่งขนาดถูก จำกัด ด้วยค่าคงที่และความยาวสตริงถูก จำกัด โดยค่าคงที่ส่งคืน\}) ทั้งสองนี้คง bounding มีทั่วโลก: พวกเขาเป็นเหมือนกันสำหรับปัจจัยการผลิตทั้งหมดTT D ( { t s | t T , s S } ) TD(S)TD({ts | tT,sS})T
  • Get-Prefixesบน : return\} โปรดทราบว่าผมไม่ทราบจริงๆสิ่งที่โครงสร้างที่ใช้สำหรับชุดนี้ตราบเท่าที่ฉันสามารถระบุเนื้อหาในเวลา{ a | s S , Σ } O ( | Σ | )D(S){a | asS,aΣ}O(|Σ|)
  • Remove-Prefixesใน : การกลับมา\})D ( { s | s S , Σ } )D(S)D({s | asS,aΣ})
  • Merge: ให้และกลับT)D ( T ) D ( S T )D(S)D(T)D(ST)

ตอนนี้ฉันต้องการดำเนินการเหล่านี้ทั้งหมดในเวลาแต่ฉันสบายดีกับโครงสร้างที่ดำเนินการทั้งหมดเหล่านี้ในเวลาโดยที่คือความยาวของสตริงที่ยาวที่สุดใน โครงสร้าง. ในกรณีของการรวมฉันต้องการเวลาทำงานโดยที่คือสำหรับอันแรกและ theสำหรับโครงสร้างที่สองo ( n ) n o ( n 1 + n 2 ) n 1 n n 2 nO(1)o(n)no(n1+n2)n1nn2n

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

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

ฉันต้องการใช้โครงสร้างดังกล่าวในอัลกอริทึมการแยกฉันกำลังทำงานอยู่; โครงสร้างข้างต้นจะเก็บ lookahead ที่ฉันต้องการสำหรับอัลกอริทึม

ฉันได้พิจารณาแล้วใช้Trieแต่ปัญหาหลักคือว่าผมไม่ทราบวิธีการที่จะผสานพยายามอย่างมีประสิทธิภาพ หากชุดสตริงสำหรับAdd-Prefix-Setประกอบด้วยสตริงอักขระเดียวเท่านั้นคุณสามารถเก็บชุดเหล่านี้ไว้ในสแต็กซึ่งจะทำให้เวลาการทำงานของคุณสำหรับการดำเนินการสามครั้งแรก อย่างไรก็ตามวิธีนี้ใช้ไม่ได้กับการรวมเข้าด้วยกันO(1)

สุดท้ายโปรดทราบว่าฉันไม่สนใจปัจจัย: นี่คงที่สำหรับทุกสิ่งที่ฉันสนใจ|Σ|


สตริงถูกสร้างขึ้นโดยการดำเนินการAdd-Prefix-Setหรือคุณเริ่มต้นด้วยชุดสตริงโดยพลการ
Joe

2
สมมติว่าก่อนที่จะดำเนินการผสานมีเป็นสตริงของความยาวทั้งSและT คุณจะตรวจสอบได้อย่างไรว่าสตริงนี้ซ้ำกันในเวลาo ( n 1 + n 2 )หรือไม่ n1=n2STo(n1+n2)
Joe

คุณเริ่มต้นด้วยชุดที่มีสตริงเดี่ยวถ่านหนึ่งตัว แต่สตริงที่ว่างเปล่าก็ใช้ได้เช่นกัน (คุณสามารถทำได้Add-Prefix-Set)
Alex ten Brink

@ Joe: นั่นเป็นคำถามที่ดี - ฉันเริ่มที่จะได้รับการเชื่อว่าการดำเนินการผสานสวยมากแบ่งโอกาสของการโครงสร้างดังกล่าวใด ๆ ...
อเล็กซ์บริงค์สิบ

หากคุณใช้การแสดงชุด "กองชุด" คุณสามารถรวมสองกองในหน่วยนาที(n1,n2)
Joe

คำตอบ:


5

ฉันคิดอยู่พักหนึ่งแล้ว แต่ไม่พบปัญหาในการดำเนินการทั้งหมดของคุณในวิธีที่โง่ที่สุดในโครงสร้าง DAG ที่มีลักษณะคล้าย Trie:

เพิ่มคำนำหน้า-Set

สร้าง Trie ของสตริงจากTเชื่อมต่อโหนดใบไม้แต่ละอันเข้ากับรูทของคู่ชีวิตเก่าT

ความซับซ้อน: O(|T|)

ผสาน

รวมรากของสองโครงสร้าง: ทำให้โหนดย่อยทั้งหมดของโหนดย่อยสองของโหนดแรก ตอนนี้คุณอาจมีขอบหลายอันที่มีตัวอักษรเหมือนกันซึ่งมาจากโหนดเดียวกัน

ความซับซ้อน: O(1)

Lazy update ของ root

  1. O(|Σ|)O(1)
  2. O(1)

Get-คำนำหน้า

ขี้เกียจอัพเดทรูท ตอนนี้หาเด็กทุกคนของรูทและรายงานชุดตัวอักษรบนขอบไปหาพวกเขา

O(|Σ|)

เอาออกคำนำหน้า

ขี้เกียจอัพเดทรูท รวมลูกทั้งหมดของรูทและตั้งค่าตัวชี้รูทเป็นผลลัพธ์ของการรวมกันนี้ ขี้เกียจอัพเดทรูทใหม่

O(|Σ|)

วิริยะ

O(1)O(|Σ|)O(logN)N

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