Bu dize işlemlerini destekleyen bir 'string stack' veri yapısı var mı?


28

Aşağıdaki işlemleri gerçekleştirebilecek bir karakter kümesi karakter kümesi üzerine bir dizi dizi depolayan bir veri yapısı arıyorum . Biz göstermektedirler dizi kümesini depolanması veri yapısı olarak .D ( S ) SΣD(S)S

  • Add-Prefix-Seton : Büyüklüğü bir sabit tarafından sınırlandırılmış ve dize uzunlukları bir sabit ile sınırlandırılmış bazı (muhtemelen boş) dizgilerin değeri verilirse , . Her ikisi de bu sınırlayıcı sabitler globaldir: bunlar tüm girişleri için aynıdır .T D ( { t s | t T , s S } ) TD(S)TD({ts | tT,sS})T
  • Get-Prefixesilgili : dönüş . İçeriğini zamanında numaralayabildiğim sürece, bu set için hangi yapının kullanıldığını gerçekten bilmiyorum .{ a | Bir s S , bir Σ } O ( | Σ | )D(S){a | asS,aΣ}O(|Σ|)
  • Remove-Prefixesilgili : geri .D ( { s | a s S , bir Σ } )D(S)D({s | asS,aΣ})
  • Merge: verilen ve , .D ( T ) D ( S T )D(S)D(T)D(ST)

Şimdi, tüm bu işlemleri zamanında yapmak isterdim , ancak tüm bu işlemleri zamanında yapan bir yapıya göre iyiyim , burada , en uzun dizenin uzunluğu yapısı. Birleştirme durumunda, bir istiyorum çalışma süresi, olup , ilk ve , ikinci bir yapı için.O ( n ) n, O ( n, 1 + n 2 ) n- 1 , n , n 2 , nO(1)o(n)no(n1+n2)n1nn2n

Ek bir gereklilik, yapının değişmez olması veya en azından yukarıdaki işlemlerin, eskilerin işaretçilerinin eskisi gibi işlev göreceği şekilde 'yeni' yapılar döndürmesidir.

İtfa payı ile ilgili bir not: bu iyi, ancak sebat etmek için dikkatli olmalısınız. Eski yapıları her zaman tekrar kullandığımda, aynı yapı üzerinde belirli bir işlem kümesiyle en kötü durumdan birini vurursam başım derde girer (yani yeni oluşturduğu yapıları yok sayarak).

Böyle bir yapıyı üzerinde çalıştığım bir çözümleme algoritmasında kullanmak istiyorum; Yukarıdaki yapı algoritma için ihtiyaç duyduğum bakışı tutacaktır.

Zaten bir trie kullanmayı düşünmüştüm , ancak asıl sorun denemeleri verimli bir şekilde nasıl birleştireceğimi bilmemem. Dizeleri Add-Prefix-Setyalnızca tek karakterli dizelerden oluşuyorsa, bu kümeleri bir yığında saklayabilirsiniz, bu da ilk üç işlem için size çalışma zamanı verir. Ancak, bu yaklaşım birleştirmek için de işe yaramıyor.O(1)

Son olarak, faktörler ile ilgilenmediğime dikkat edin: bu umurumda olan herkes için aynı.|Σ|


Dizeler yalnızca işlem tarafından mı oluşturulmuş Add-Prefix-Setveya rastgele bir dizi dizeyle mi başlıyorsunuz?
Joe

2
Bir birleştirme işlemi önce, uzunluğunun bir dizi olduğunu varsayalım hem de S ve T . Bu dizginin o ( n 1 + n 2 ) süresinde bir kopyası olup olmadığını nasıl anlayabilirsiniz ? n1=n2STo(n1+n2)
Joe

İçinde bir tane char karakterli bir karakter dizisi ile başlarsınız, fakat boş bir karakter dizisi de iyidir (sadece girebilirsiniz Add-Prefix-Set)
Alex ten Brink

@Joe: Bu iyi bir soru - Birleştirme operasyonunu böyle bir yapıya kavuşturma şansını kıracağı konusunda ikna olmaya başladım ...
Alex ten Brink

"Set yığını" gösterimini kullanıyorsanız, iki yığını en az dakikada birleştirebilirsiniz (n1,n2)
Joe

Yanıtlar:


5

Uzunca bir süre düşündüm, fakat tüm operasyonlarınızı en aptalca bir DAG yapısında yapıyorum.

Add-Önek-Set

dizisinden oluşan bir trie oluşturun . Her bir yaprak düğümünü eski trie köküne bağlayın.T

Karmaşıklık: O(|T|)

Birleştirme

İki yapının köklerini birleştirin: tüm alt düğümleri, ilk düğümün ikinci kök alt öğelerinin tüm alt düğümlerini yapın. Şimdi aynı düğümden aynı karakterle işaretlenmiş çoklu kenarlara sahip olabilirsiniz.

Karmaşıklık: O(1)

Kökün tembel güncelleme

  1. Her karakter için, bu karakterle işaretlenmiş kenarlardan erişilebilen bütün kökün çocuklarını birleştirin. ( + Şimdiye kadar eklenen her kenar için Amortize O ( 1 ) )O(|Σ|)O(1)
  2. Köke giden tüm kenarları üstten silin. (Kaldır öneklerinden sonra olabilir, eklenmiş her kenar için itfa edilir )O(1)

-Önekleri alın

Tembel kökü güncelleyin. Şimdi kökün tüm çocuklarını bulun ve onlara giden kenarlardaki harf kümesini bildirin.

Karmaşıklık: O(|Σ|)

Kaldır-önekleri

Tembel kökü güncelleyin. Kökün tüm çocuklarını birleştirin ve kök işaretçisini bu birimin sonucuna ayarlayın. Tembel yeni kökü güncelleyin.

O(|Σ|)

süreklilik

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.