N dizeleri verildiğinde, bunlardan biri diğerinin bir alt dizisi mi?


9

Bize bir koleksiyon verildiğini varsayalım n Teller, S1,...,Sn. Bu dizelerden herhangi birinin koleksiyondaki başka bir dizenin bir alt dizesi olup olmadığını bilmek istiyorum. Başka bir deyişle, aşağıdaki görev için bir algoritma istiyorum:

Giriş: S1,...,Sn

Çıktı: ben,j öyle ki Sben bir alt dizesi Sj ve benjveya böyle bir şey yoksa Hiçbiri ben,j var olmak

Bunun için etkili bir algoritma var mı?

"Alt dize" yi "önek" ile değiştirirsek, etkili bir algoritma vardır (dizeleri sıralayın, ardından bitişik dizeleri karşılaştırmak için doğrusal bir tarama yapın; sıralama alt dizelerin bitişik olmasını sağlayacaktır). Ancak, herhangi bir dizenin diğer dizelerin bir alt dizesi olup olmadığını test etmek daha zor görünmektedir. Saf bir algoritma tüm çiftleri tekrarlamaktırben,j, ancak bu gerektirir Θ(n2)substring testleri. Daha verimli bir algoritma var mı?

Sanırım bu "tüm çiftler alt dize testi" ya da bunun gibi bir şey diyebiliriz.

Nihai hedefim, koleksiyondaki başka bir şeyin alt dizesi olan her birini kaldırarak hiçbir dize, başka bir alt dize olmayacak şekilde koleksiyonu budamaktır.


İpucu: Sonek dizisi.
Takma isim

Yan not olarak, Θ(n2)alt dizeleri bulduğunuz gibi kaldırırsanız doğru değildir. Daha az olacak. Ayrıca, daha uzun bir dize daha kısa bir dizede görünemeyeceğinden uzunluğa göre sıralamanız gerekir. TekrarΘ(n2)burada yanlış.
Alexis Wilke

@AlexisWilke, Θ(n2)doğrudur: en kötü durumda alt dize testlerinin sayısıdır (en kötü durum hiçbir dizginin diğerinin bir alt dizesi olmadığı durumdur). Uzunluğa göre sıralama size asimptotikleri etkilemeyen sadece iki faktör verir.
DW

Yanıtlar:


6

Doğrusal zamanda bir sonek ağacı oluşturabilir ve tam bir dizeye (düğüm başına sabit süre) karşılık gelen bir iç düğüm olup olmadığını kontrol edebilirsiniz.

Daha ayrıntılı olarak, bize dizeler verildiğini varsayın s1,...,snΣ*.

  1. (Genelleştirilmiş) bir sonek ağacı oluşturuns1$1,s2$2,...,sn$n ile n çiftli ayrı terminal işaretleyicileri $1,...,$nΣ.

    Ukkonen algoritmasını kullanarak , bu doğrusal zamanda yapılabilir; tüm dize uzunluklarının toplamında doğrusal.

  2. Yaprakları etiketlediğinizi varsayarsak (ben,j) eğer son eki temsil ediyorsa sben[j..|sben|] nın-nin sben, ağacın üzerinden geçin ve bunları bulun n etiketli yapraklar (ben,0), yani tam dizelere karşılık gelen yapraklar.

    Bu, girdi boyutunda doğrusal olan ağaç boyutunda doğrusal zaman alır.

  3. Ebeveyninin soyundan gelen yapraklar (ben,0) (buna etiketli bir kenar ile ulaşılır $ben) kümedeki tüm eşleşmeleri temsil eder; bu sonek ağaçlarının temel değişmezinden gelir. Herhangi bir yaprağa inerek herhangi bir eşleşmeyi bulun (ancak(ben,0)).

    Bu yine doğrusal zaman alır.

Farklı terminal işaretleyicileri gerçekten gerekli değildir; yaprak başına birden çok etikete izin verdiğiniz sürece tüm dizeleri sonlandırmak için kullanılan tek bir sayfa oldukça yeterlidir.

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.