Burada yapabileceğiniz birkaç ticaret off vardır. Diyelim ki elemanları iki takım var olduğunu varsayalım, S ve T, biz belirlemek istiyoruz bir evren U'dan çizilmiş S ≥ T. Verilen örneklerden birinde,
var
S={1,2,3,4}
T={3,4,5}
U={1,2,3,4,5}
1. Sorted Lists (or balanced search tree)
The method suggested by most posters. If you already have sorted lists, or don't care about the length of time it takes to create them (say, you're not doing that often), then this algorithm is basically linear time and space. This is usually the best option.
(Uygun yerlerde, ancak bu genellikle relivant değil "| | U Log" Burada diğer seçimler adil olmak için, zaman ve mekan sınırları aslında faktörleri içermelidir)
Data structures: S ve T. her Yoksa sürekli uzayda iterated dengeli bir arama ağacı (örn. AVL ağacı, kırmızı-siyah ağaç, B +-tree) için sıralama listesi.
Algorithm: T her eleman için, sırayla, arama, o öğenin doğrusal S. Her arama bıraktığınız yerden hatırlıyorum ve orada bir sonraki arama başlatın. Her arama başarılı olursa, o zaman S ≥ T.
Time complexity: yaklaşık O( | S | Giriş | S | + | T | Giriş | T | ) sıralı listeleri oluşturmak için, {[(1)] } max (| S |, | T |) ) karşılaştırmak.
Space complexity, yaklaşık O( | S | + | T | )
Example (C++)
#include <set>
#include <algorithm>
std::set<int> create_S()
{
std::set<int> S;
// note: std::set will put these in order internally
S.insert(3);
S.insert(2);
S.insert(4);
S.insert(1);
return S;
}
std::set<int> create_T()
{
std::set<int> T;
// note std::set will put these in order internally
T.insert(4);
T.insert(3);
T.insert(5);
return T;
}
int main()
{
std::set<int> S=create_S();
std::set<int> T=create_T();
return std::includes(S.begin(),S.end(), T.begin(), T.end());
}
2. Hash tables
Better average time complexity than with a sorted list can be obtained using hash tables. The improved behavior for large sets comes at the cost of generally poorer performance for small sets.
Sıralanan listeleri gibi, ben evrenin büyüklüğüne göre katkıda karmaşıklığını görmezden geliyorum.
Data structure: S için Hash tablo, T. çabuk iterable şey
Algorithm: kendi hashtable içine S her elemanını takın. Daha sonra, T her öğe için, bu karma tablo olmadığını görmek için kontrol edin.
Time complexity: O( | S | + | T | ) kurmak, O( | T | ) karşılaştırmak için.
Space complexity, O( | S | + | T | )
Example (C++)
#include <tr1/unordered_set>
std::tr1::unordered_set<int> create_S()
{
std::tr1::unordered_set<int> S;
S.insert(3);
S.insert(2);
S.insert(4);
S.insert(1);
return S;
}
std::tr1::unordered_set<int> create_T()
{
std::tr1::unordered_set<int> T;
T.insert(4);
T.insert(3);
T.insert(5);
return T;
}
bool includes(const std::tr1::unordered_set<int>& S,
const std::tr1::unordered_set<int>& T)
{
for (std::tr1::unordered_set<int>::const_iterator iter=T.begin();
iter!=T.end();
++iter)
{
if (S.find(*iter)==S.end())
{
return false;
}
}
return true;
}
int main()
{
std::tr1::unordered_set<int> S=create_S();
std::tr1::unordered_set<int> T=create_T();
return includes(S,T);
}
3. Bit sets
If your universe is particularly small (let's say you can only have elements 0-32), then a bitset is a reasonable solution. The running time (again, assuming you don't care about setup time) is essentially constant. In the case you do care about setup, it's still faster than creating a sorted list.
Ne yazık ki, bit kümeleri hatta orta büyüklükteki bir evren için çok hızlı bir şekilde hantal hale gelir.
Data structure, bit S her biri için vektör (genellikle bir makine tam sayı) ve T. Biz = 11110 S kodlamak ve T = 00111, verilen örnekte olabilir.
Algorithm: sonuç T, daha sonra S ≥ T. eşitse T. gelen bit ile S her bit bitsel 've' bilgisayar tarafından, kavşak hesaplayın
Time complexity: O( | U | + | S | + | T | ) kurulumu, O( | U | {[(2 )]} karşılaştırmak.
Space complexity, O( | U | )
Example: (C++)
#include <bitset>
// bitset universe always starts at 0, so create size 6 bitsets for demonstration.
// U={0,1,2,3,4,5}
std::bitset<6> create_S()
{
std::bitset<6> S;
// Note: bitsets don't care about order
S.set(3);
S.set(2);
S.set(4);
S.set(1);
return S;
}
std::bitset<6> create_T()
{
std::bitset<6> T;
// Note: bitsets don't care about order
T.set(4);
T.set(3);
T.set(5);
return T;
}
int main()
{
std::bitset<6> S=create_S();
std::bitset<6> T=create_T();
return S & T == T;
}
4. Bloom filters
All the speed benefits of bitsets, without the pesky limitation on universe size the bitsets have. Only one down side: they sometimes (often, if you're not careful) give the wrong answer: If the algorithm says "no", then you definitely don't have inclusion. If the algorithm says "yes", you might or might not. Better accuracy is attained by choosing a large filter size, and good hash functions.
Onlar ve yanlış cevaplar verecek, Bloom filtreleri korkunç bir fikir gibi gelebilir göz önüne alındığında. Ancak, belirli bir kullanım alanı vardır. Genellikle bir hızla birçok dahil denetimlerini yapmak Bloom filtreleri kullanın ve daha sonra gerektiğinde doğruluğunu garanti için daha yavaş bir deterministik yöntemini kullanırsınız. Bağlantılı Wikipedia makale Bloom filtreleri kullanarak bazı uygulamalar bahseder.
Data structure: A Bloom filter süslü bitset olduğunu. Önceden bir filtre boyutu ve hash fonksiyonları seçmelisiniz.
Algorithm (kroki): 0 Bit kümesiyle başlatma, bir çiçek filtreye bir öğe eklemek, her hash fonksiyonu ile karma ve bitset uygun biti ayarlamak için.. Içermenin belirlenmesi sadece bit kümeleri gibi çalışıyor.
Time complexity, O( filter size )
Space complexity, O( filter size )
Probability of correctness: o "S T içermez" için cevap verirse her zaman doğru. (| S | x | T | / (filter size)) Bu cevap) ise "S T içerir" Something ^ 0,6185 gibi. Doğruluk makul bir olasılık vermek | T | S | | Özel olarak, filtre boyutu ürününe orantılı seçilmelidir ve.