सेट अंतर के लिए डेटा संरचना?


21

क्या कोई डेटा संरचना है जो निम्नलिखित कार्यों का समर्थन करते हुए सेट (परिमित ग्राउंड सेट) का संग्रह बनाए रखती है? किसी भी उदासीन चल रहे समय की सराहना की जाएगी?

  1. एक खाली सेट में प्रवेश करें।
  2. एक सेट में एक तत्व जोड़ें।
  3. दो सेट को देखते हुए, रिपोर्ट करें कि क्या वे प्रतिच्छेद करते हैं।

1
यह एक बहुत ही सामान्य प्रश्न है, क्योंकि कोई भी डेटा संरचना परिमित डोमेन के साथ उन कार्यों का समर्थन कर सकती है। क्या आपके द्वारा कुछ अधिक विशिष्ट हुआ जा सकता है ? उदाहरण के लिए। आपको किस जटिलता की आवश्यकता है, आप सेट ऑपरेशन आदि प्राप्त करने के लिए क्या बलिदान करना चाहते हैं
बार्टोज़ प्रेज़ीबल्स्की

जवाबों:


13

यदि प्रत्येक सेट में अन्य सेट मौजूद हैं, और आपके पास कुल s>0 सेट का रिकॉर्ड है, तो आप किसी संग्रह के लिए किसी भी डेटा संरचना को आसानी से चालू कर सकते हैं ( जैसे बाइनरी सर्च ट्री, इत्यादि ) जिसमें आप पुनर्प्राप्ति कर सकते हैं। में दो सेटों के प्रतिच्छेदन का एक तत्व O(logs)

  • प्रत्येक सेट में कुछ पूरी तरह से ऑर्डर किए गए सेट से एक अद्वितीय पहचानकर्ता होना चाहिए। यदि आप स्पष्ट रूप से अपने सेट नाम रखते हैं ,S1,S2, तो पहचानकर्ता सिर्फ सूचकांक हो सकता है।

  • आपको सेट की "रजिस्ट्री" को लागू करना चाहिए; एक डेटा संरचना जो आपके द्वारा परिभाषित सभी सेटों का एक संग्रह रखता है। रजिस्ट्री को खोज-ट्री डेटा संरचना के रूप में लागू किया जाना चाहिए, ताकि आसान पुनर्प्राप्ति की अनुमति दी जा सके ( जैसे  यदि आप सेट को हटाना चाहते हैं) और सेट के रैखिक-समय ट्रैवर्सल।

  • प्रत्येक सेट अन्य सेटों में से प्रत्येक का "इंडेक्स" भी बनाए रखता है - उनकी प्रति नहीं , बल्कि एक डेटा संरचना जो अन्य सेट के लेबल द्वारा अनुक्रमित होती है। इस इंडेक्स का उपयोग प्रत्येक सेट S k के लिए , S jS k के सभी तत्वों के एक द्विआधारी खोज ट्री के लिए किया जाएगा । (दो सेट S j और S k उस खोज ट्री की एक प्रति साझा करते हैं।)SjSkSjSkSjSk

प्रारंभ

एक सेट के प्रारंभ के होते हे ( 1 ) के संचालन उसके तत्वों का पेड़ प्रारंभ करने, हे ( रों ) आपरेशन के रूप में आप को प्रारंभ (रजिस्ट्री से कॉपी) सेट के लिए सूचकांक टी , और हे ( रों लॉग रों ) आप के रूप में संचालन रजिस्ट्री जोड़ने के लिए पार टी अन्य सेटों में से प्रत्येक के सूचकांकों में एस जे । के सूचकांक में टी , हम का प्रतिनिधित्व खोज पेड़ बनाने टी एस जे = T=O(1)O(s)TO(slogs)TSjTTSj=अन्य सेटों के लिए ; हम एस जे के सूचकांक के लिए उसी पॉइंटर को कॉपी करते हैं ।SjSj

एक सेट टी में एक तत्व जोड़नाT

कुछ जोड़ा जा रहा है सेट करने के लिए टी समय लगता हे ( लॉग ऑन एन टी ) हमेशा की तरह है, जहां के रूप में एन टी = | टी | । हम यह भी की सदस्यता के लिए परीक्षण एक्स अन्य सेट में से प्रत्येक में एस 1 , एस 2 , ... , जो समय लगता है हे ( लॉग एन एस 1 + लॉग ऑन एन एस 2 + ) हे ( रों लॉग nxVTO(lognT)nT=|T|xS1,S2, जहाँ n = | वी | ब्रह्मांड का आकार (या सबसे बड़ा सेट S j ) है और s रजिस्ट्री में सेट की संख्या है। प्रत्येक सेट के लिए एस जे ऐसी है कि एक्स एस जे , यह भी डालने एक्स सेट के लिए सूचकांक में एस जेटी । ऐसे प्रत्येक सेट के लिए एस जे , इस लेता हे ( लॉग रों + लॉग एन टी ) को देखने के लिए समय, एस जे

O(lognS1+lognS2+)O(slogn),
n=|V|SjsSjxSjxSjTSjO(logs+lognT)Sj को इंडेक्स में देखने के लिए और करने के लिए डालने एक्स में एस जेटी ; सभी सेटों में S 1 , S 2 , ... इसमें समय लगता है O ( s log s + s log n T ) । अगर हम मान लें कि सेट की संख्या एस जे ज्यादा ब्रह्मांड के आकार से कम है वी (जो है, अगर हम मान लें कि रों « n ), तत्व प्रविष्टि के लिए कुल समय तो है हे ( रों लॉग एन )TxSjTS1,S2,O(slogs+slognT)SjVsnO(slogn)

आप सेट में डुप्लिकेट की अनुमति नहीं देते हैं, तो हम इस मामले में समय बचा सकते हैं कि पहले से ही सदस्यता परीक्षण और अन्य सेट के लिए सम्मिलन forgoing द्वारा टी । "सम्मिलन" उस स्थिति में जब x पहले से मौजूद है तो केवल O ( लॉग एन T ) में समय लगता है ।xSTxO(lognT)

अंतःक्रिया परीक्षण

प्रत्येक सेट का सूचकांक सटीक रूप से बनाए रखा जाता है ताकि दो सेट और एस के प्रतिच्छेदन का त्वरित मूल्यांकन हो सके । एक सेट के लिए एस जे , बस सेट के लिए अपने सूचकांक की जाँच करके एस कश्मीर , हम केवल कुछ ही समय में निर्धारित नहीं कर सकता हे ( लॉग रों ) या नहीं, एस जे intersects एस कश्मीर , लेकिन हम भी एक द्विआधारी पूरे सेट युक्त पेड़ प्राप्त कर सकते हैं एस जेएस केSjSkSjSkO(logs)SjSkSjSk

तत्व निकालना

एक तत्व को हटाने के लिए एक सेट से टी , हम इसे न केवल खोज के लिए पेड़ से हटाने टी ही है, लेकिन चौराहों में से प्रत्येक से एस जेटी सेट के लिए एस जे अपने सूचकांक में। इसमें O ( s log n T ) का समय लगता है , जहां n T = | टी | xTTSjTSjO(slognT)nT=|T|

हटाओ सेट

रजिस्ट्री को खोजने के ओवरहेड के कारण, यदि आपके पास कई सेट हैं, तो सेट को हटाने के लिए वांछनीय हो सकता है, क्योंकि उन्हें अब ज़रूरत नहीं है। संपूर्ण रजिस्ट्री का पता लगाकर, हम को हटा सकते हैंS from the index of all other sets Sj in time O(snT), dominated by the cost of deleting the search tree representing SjT for each of the other sets Sj, where nT=|T|.

Remarks

If you expect only to implement a constant number of sets, then the above run-times reduce to:

  • initialization: O(1)

  • O(logn)

  • O(1)

  • O(lognT)

  • O(nS)

nnT=|T|T

यदि आप अपेक्षा करते हैंO(|V|) sets, where V is your universe, you may need a different data structure if you want these operations to operate in sub-linear time. However, if you have pairs of sets whose intersection you know you will never test, you might be able to reduce the size of the index for the sets (by not including any sets whose intersection you will test) or use more than one registry (one for each collection of sets whose intersection you might test). In fact, a registry is only useful if you want centralized control of ensuring that each pair of sets has a record of each other in the index: it may be practical in some cases, at the initialization of a set S, simply to record ad hoc each new set into the indices of the other sets T whose intersection with S you are interested in.


6

There are data structures that allow you to do this in less than linear time, even for worst-case inputs. See http://research.microsoft.com/pubs/173795/vldb11intersection.pdf (and the papers references in there).

If your two sets S and T have a large intersection and you have a dictionary for S, looking up elements of T in random order should quickly give you a common element. The most difficult case is when the intersection size is 0 or 1.


3

Usually your programming language of choice will support a data structure with unique elements. In general there are three popular approaches: Trees, Hashes and Bitmasks. Tree elements must be comparable, Hash elements must be hashable and Bitmask elements must have some way of conversion to integers.

A tree-set will support insertion in O(log n) and intersection testing in Worst Case O(n log n).

A hash-set will support insertion in Amortized O(1*h) where 'h' is the running time of the hashing algorithm, and intersection test in Worst Case O(n).

Bitmask sets are not generally used like tree- and hash-sets.


2
This would be a decent Stack Overflow answer, but here we'd like some detail on how and why it works.
Raphael

3

If your case allows false positive answers, I'd use Bloom Filter with a single hash function.

You can implement it as follows :

Init an empty set

  • B = bit array of n bits, all set to 0.(n should be chosen according to the number of possible elements)

Add an element to a set.

  • B[hash(element)]=1

Given two sets(B1,B2), report whether they intersect.

  • check if B1 AND B2 = 0

Complexity

  • If n is not too big, all operations are O(1).
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.