यह जाँचने के बारे में कोई विचार है कि क्या वह सूची दूसरे की सबसेट है?
विशेष रूप से, मेरे पास है
List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };
LINQ का उपयोग करके यह कैसे जांचें कि t2 t1 का सबसेट है?
यह जाँचने के बारे में कोई विचार है कि क्या वह सूची दूसरे की सबसेट है?
विशेष रूप से, मेरे पास है
List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };
LINQ का उपयोग करके यह कैसे जांचें कि t2 t1 का सबसेट है?
जवाबों:
bool isSubset = !t2.Except(t1).Any();
सेट के साथ काम करने पर सूची के बजाय हैशसेट का उपयोग करें। तो आप बस IsSubsetOf () का उपयोग कर सकते हैं
HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};
bool isSubset = t2.IsSubsetOf(t1);
क्षमा करें कि यह LINQ का उपयोग नहीं करता है। :-(
यदि आपको सूचियों का उपयोग करने की आवश्यकता है, तो @ जारेड का समाधान कैविएट के साथ काम करता है जिसे आपको किसी भी दोहराया तत्वों को हटाने की आवश्यकता होगी जो मौजूद हैं।
यदि आप इकाई-परीक्षण कर रहे हैं तो आप CollectionAssert.IsSubsetOf विधि का भी उपयोग कर सकते हैं :
CollectionAssert.IsSubsetOf(subset, superset);
उपरोक्त मामले में इसका मतलब होगा:
CollectionAssert.IsSubsetOf(t2, t1);
यह यहां तैनात अन्य लोगों की तुलना में काफी अधिक कुशल समाधान है, विशेष रूप से शीर्ष समाधान:
bool isSubset = t2.All(elem => t1.Contains(elem));
यदि आप t2 में एक भी तत्व पा सकते हैं जो t1 में नहीं है, तो आप जानते हैं कि t2 t1 का सबसेट नहीं है। इस पद्धति का लाभ यह है कि यह सभी जगह में किया जाता है, बिना अतिरिक्त स्थान आवंटित किए, उपयोग किए गए समाधानों के विपरीत। इसके अलावा, इस समाधान को तोड़ने में सक्षम है जैसे ही यह एक एकल तत्व पाता है जो सबसेट स्थिति का उल्लंघन करता है, जबकि अन्य खोज जारी रखते हैं। नीचे समाधान का इष्टतम लंबा रूप है, जो उपरोक्त शॉर्टहैंड समाधान की तुलना में मेरे परीक्षणों में केवल तेजी से है।
bool isSubset = true;
foreach (var element in t2) {
if (!t1.Contains(element)) {
isSubset = false;
break;
}
}
मैंने सभी समाधानों के कुछ अल्पविकसित प्रदर्शन विश्लेषण किया, और परिणाम बहुत कठोर हैं। ये दोनों समाधान .Except () और .Intersect () समाधानों की तुलना में लगभग 100x तेज़ हैं, और अतिरिक्त मेमोरी का उपयोग नहीं करते हैं।
!t2.Except(t1).Any()
तो कर रहा है। Linq आगे पीछे काम कर रहा है। Any()
पूछ रहा है IEnumerable
कि क्या कम से कम एक तत्व है। इस परिदृश्य t2.Except(t1)
में केवल पहले तत्व का उत्सर्जन हो रहा है t2
जो अंदर नहीं है t1
। के पहले तत्व हैं t2
में नहीं है t1
यह सबसे तेजी से खत्म, अगर के सभी तत्वों t2
में हैं t1
यह सबसे लंबे समय तक चलता है।
t1={1,2,3,...9999}
और t2={9999,9998,99997...9000}
, आपको निम्नलिखित माप मिलते हैं !t2.Except(t1).Any(): 1ms -> t2.All(e => t1.Contains(e)): 702ms
:। और यह सीमा जितनी बड़ी होती जाती है।
t2.Except (t1)
एक लौटा रहा है IEnumerable
नहीं एक Collection
। यह तभी संभव आइटम के सभी का उत्सर्जन करता है, तो आप पूरी तरह से इस पर उदाहरण के लिए पुनरावृति, ToArray ()
या ToList ()
या उपयोग foreach
के अंदर तोड़ने के बिना। उस अवधारणा के बारे में अधिक पढ़ने के लिए लाइनक आस्थगित निष्पादन के लिए खोजें ।
t2={1,2,3,4,5,6,7,8}
t1={2,4,6,8}
t2.Except(t1)
=> t2 का पहला तत्व = 1 => 1 से t1 का अंतर 1 है ({2,4,6,8} के खिलाफ जाँच) => Except()
प्रथम तत्व का उत्सर्जन करता है 1 => Any()
एक तत्व => प्राप्त करता है Any()
t2 में तत्वों की सही जाँच नहीं होने पर परिणाम सत्य है।
@Cameron और @Neil से उत्तरों पर निर्माण मैंने एक विस्तार विधि लिखी है जो कि एन्यूमरेबल क्लास के समान शब्दावली का उपयोग करती है।
/// <summary>
/// Determines whether a sequence contains the specified elements by using the default equality comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence in which to locate the values.</param>
/// <param name="values">The values to locate in the sequence.</param>
/// <returns>true if the source sequence contains elements that have the specified values; otherwise, false.</returns>
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> values)
{
return !values.Except(source).Any();
}
इसे इस्तेमाल करे
static bool IsSubSet<A>(A[] set, A[] toCheck) {
return set.Length == (toCheck.Intersect(set)).Count();
}
यहाँ विचार यह है कि Intersect केवल उन मानों को लौटाएगा जो दोनों Arrays में हैं। इस बिंदु पर यदि परिणामी सेट की लंबाई मूल सेट के समान है, तो "सेट" के सभी तत्व "चेक" में भी हैं और इसलिए "सेट" "टॉच" का सबसेट है।
नोट: यदि "सेट" में डुप्लिकेट है तो मेरा समाधान काम नहीं करता है। मैं इसे नहीं बदल रहा हूं क्योंकि मैं अन्य लोगों के वोटों को चुराना नहीं चाहता।
संकेत: मैंने कैमरन के जवाब के लिए मतदान किया।