2011-05-09 24 views
5

की सुविधा देता है कहते हैं कि मैं तार की एक सूची है:दो सूचियों का पूरक?

ए, बी, सी, डी

फिर तार

का एक और सूची

बी, सी, डी

मैं जानना चाहता हूँ कि क्या तत्वों पहली सूची में हैं जो दूसरी सूची में नहीं हैं, इसलिए परिणाम

मुझे ऐसा करने के लिए एक्सटेंशन विधि का नाम नहीं पता है। मुझे पता है कि मैं समान सूची तुलना के लिए कॉन्सट, यूनियन, छेड़छाड़ का उपयोग कर सकता हूं, लेकिन इस विशेष कार्य को पूरा करने के लिए नाम को नहीं जानता।

परिशिष्ट, मैं डुप्लिकेट में दिलचस्पी है, तो अगर पहले सूची है:

ए, ए, ए, बी, सी, डी

और दूसरी सूची

बी, सी है , डी

मैं

A, A प्राप्त करना चाहते हैं, एक

धन्यवाद!

+1

यदि आप छोटी सूचियों के साथ कुछ बार से अधिक करते हैं तो सेट का उपयोग करें। यह न केवल एक और अधिक उचित दृष्टिकोण है, एक हजार गुना बेहतर जटिलता के अनुसार। – delnan

+0

धन्यवाद, समस्या में हजारों पंक्तियां शामिल हैं – sooprise

उत्तर

14

आप Except Extension Method उपयोग कर सकते हैं एक सूची के सभी तत्वों कि एक दूसरी सूची में नहीं हैं पाने के लिए:

var result = list1.Except(list2); 
+0

क्या यह डुप्लिकेट करता है? – sooprise

+0

मैं डुप्लीकेट – sooprise

3
var result = list1.Where(i => !list2.Contains(i)); 
+0

इसके लिए विस्तारित विधि नहीं है? – sooprise

+0

+1 यह वही है जो मैं करता हूं। –

+0

आप एक विस्तार विधि बना सकते हैं जो ऐसा करता है। –

4

"सिवाय" बीसीएल में विधि सभी डुप्लिकेट निकाल देता है, जो नहीं क्या है तुम्हें चाहिए।

यदि समस्या में सूचियां बड़ी हैं, तो यह प्रभावी ढंग से करने के लिए आप शायद समय पर बचत के लिए स्मृति बर्बाद करना चाहते हैं। कुछ ऐसा:

// yield all members of "sequence" omitting those in "except" 
static IEnumerable<string> Filter(
    this IEnumerable<string> sequence, 
    IEnumerable<string> except) 
{ 
    var set = new HashSet<string>(except); // Burn memory to save time 
    return from item in sequence 
      where !set.Contains(item) 
      select item; 
} 

इस तरह आप किसी आइटम का परीक्षण करते समय हर बार तेज़ लुकअप प्राप्त करते हैं। एक बैग:

var sequence = new List<string>() { A, B, A, C, D }; 
var except = new List<string>() { B, C }; 
var result = sequence.Filter(except).ToList(); 
+1

चाहता हूं ध्यान दें कि यदि पहली सूची ए, ए, बी और दूसरी सूची ए है, तो यह बी वापस आ जाएगी। – Brian

0

तो डुप्लिकेट की अपनी परिभाषा दोनों सूचियों और आप कुशलता से पूरक की गणना करना चाहते हैं शामिल हैं के साथ कॉल, तो आप एक अलग डेटा संरचना का उपयोग करने की आवश्यकता होगी। एक बैग एक सेट है जो डुप्लिकेट की अनुमति देता है।

यहां एक विस्तार विधि है जिसे BagDifference कहा जाता है जो कुशलतापूर्वक एरिक के उत्तर से प्रेरित नमूना कार्यक्रम के साथ एक साथ सूची में डुप्लिकेट के लिए खाता है।

public class Bag<T> : Dictionary<T, int> 
{ 
    public Bag(IEnumerable<T> sequence) 
    { 
     foreach (var item in sequence) 
     { 
      if (!ContainsKey(item)) this[item] = 0; 
      ++this[item]; 
     } 
    } 
} 

public static class EnumerableExtensions 
{ 
    public static IEnumerable<T> BagDifference<T>(this IEnumerable<T> sequence1, IEnumerable<T> sequence2) 
    { 
     var bag1 = new Bag<T>(sequence1); 
     var bag2 = new Bag<T>(sequence2); 
     foreach (var item in bag1.Keys) 
     { 
      var count1 = bag1[item]; 
      var count2 = bag2.ContainsKey(item) ? bag2[item] : 0; 
      var difference = Math.Max(0, count1 - count2); 
      for (int i = 0; i < difference; i++) 
       yield return item; 
     } 
    } 
} 

class Program 
{ 

    static void Main(string[] args) 
    { 
     var sequence = new List<string>() { "A", "B", "A", "C", "D" }; 
     var except = new List<string>() { "A", "B", "C", "C" }; 
     var difference = sequence.BagDifference(except).ToList(); 
    } 
} 
संबंधित मुद्दे