İşte bir süredir beni rahatsız eden bir sorun. Dize diyelim 1s ve 0s dizisidir ve joker karakter dizesi 1, 0 ve? S dizisidir. Tüm dizeler ve joker karakter dizeleri aynı uzunlukta. Bunlar standart UNIX joker karakterleri; 10 ?? 1 maçlar 10011, 10111, vb - a? bu konumda 1 veya 0 ile eşleşir. Eğer ve joker karakter dizeleridir, o zaman yazıyoruz her dize ile eşleşiyorsa tarafından da eşleştirildi .
Sorunlar : bir set verildi joker dizeleri ve bir sorgu (ayrıca bir joker karakter dizesi), öyle ki ? Ve eğer değilse, ekleyebilir miyiz için verimli?
İşte bariz çözüm (nerede dizelerin boyutu, RAM'in kelime boyutu (genellikle 32 veya 64)): listenin her bir öğesini gözden geçirin ve koşulu test edin (bit-twiddling kullanılarak 2 veya 3 işlemle yapılabilir). Ayrıca, herhangi bir öğe için tutar biz tararken. Eğer testimizi geçemez, sonra ekleyin ayarlayın ve işaretledik.
Ama bu yeterince hızlı değil. Bir şey olsaydı gerçekten harika olurdu çözüm veya mükemmel bir dünyada, bir sayı tabanı ağacına benzer karmaşıklık (). Ayrıca, sorguların yaklaşık olarak doğru olması da uygundur :, sonra evet ya da hayır; ama durum kesinlikle yoksa hayır geri dönün.
Bu en kötü durum karmaşıklığına yardımcı olmasa da, tüm öğelerin bir joker karakter dizesiyle sınırlıdır; yani, bazı var öyle ki herkes için , .
Denediğim fikirler
- Joker karakter dizeleri bir birleştirme-yarı-dilimi oluşturur. Joker karakter dizelerini tutan bir n-ary ağacımız olabilir; yapraklar joker karakter dizileri olacak ve dallar tüm çocukların birleşmesini temsil edecekti. Sorgu ve birleştirme karşılaştırılamazsa, o daldaki tüm çocuklarla karşılaştırmaya çalışırken zaman kaybetmek zorunda değiliz. Ayrıca, bir güncelleme yaparsak ve güncelleme bir birleştirmeden daha büyük olursa, tüm şubeyi silebiliriz. Ne yazık ki, bu hala en kötü durumda ve ağaç eklemek için her zaman "en iyi" birleşimleri bulamıyoruz.
- Kişi bir sayı tabanı oluşturabilir . Biz biliyoruz kibazı joker karakter dizeleriyle sınırlıdır; varsayalım ki? 0? 0. Daha sonra, trie'nin tüm dalları sadece dizelerin 1. ve 3. bitlerinde olmalıdır. Sorgunun dallandığımız geçerli bit 1 ise,? ve 1 şube; 0 ise,? ve 0 dal; öyleyse ?, biz sadece kontrol? dalı. Potansiyel olarak birden fazla dal almamız gerektiğinden, bu çok iyi görünmüyor (aynı nedenden dolayı üçgeni güncellemek zor). Eşleştirme çok hızlı bir işlem olduğundan, bir ağaçta çok fazla hareket yapmak için naif stratejiye kıyasla acıyor (bir grup işaretçi izlemek bazı OR'ler ve AND'ler yapmaktan çok daha pahalıdır).
Alakalı iş
Ağ topluluğunda, bu sorun "paket sınıflandırması" olarak ortaya çıkmaktadır, burada bilinen algoritmaların ve veri yapılarının iyi bir araştırması bulunmaktadır . Ne yazık ki, hemen hemen her zaman joker karakter dizelerinin yalnızca öneklerle eşleştiği varsayılmaktadır ve sorgu bu dizelerin bir demetidir. Tabii ki, genel bir joker karakter dizesini her zaman şu ölçütleri karşılayacak şekilde dönüştürebiliriz: 1? 00? 1 ?? (1,?, 0, 0,?, 1,?,?). Ancak bu etkili olmaz. Diğer varsayım, bu tuple'lerin bir "renk" ile ilişkili olduğudur ve sorgulamanın rengi döndürmesi gerekir (sadece eşleştiği değil). Bu, sorunu daha da zorlaştırır, çünkü tuples'i sipariş etmeliyiz (ya da (0,?) Ve (?, 1) eşleşmelerinden (0, 1) hangisinin belirsiz olduğu).
Algoritmalar topluluğunda "umurumda değil" ile eşleşen alt dizeleri bulmakla ilgili birçok sonuç buldum. Bu oldukça zor bir problem ve tekniklerin hiçbirini gerçekten kullanamıyorum.
Sonuç olarak
Herhangi bir yardım için teşekkürler!