2013-01-08 14 views
10

मैं दो सूची की तुलना करने के लिए एक छोटा प्रोग्राम लिख रहा हूं। यदि मान समान हैं, तो मैं उन्हें डुप्लिकेट करने के लिए जोड़ता हूं, यदि वे अलग हैं, तो मैं उन्हें अलग-अलग जोड़ता हूं। मैंने देखा कि मेरे कुछ मूल्य जोड़े गए हैं और कुछ नहीं हैं, और थोड़ी देर के लिए डिबगिंग के बाद, मुझे यकीन नहीं है कि समस्या क्या है। क्या कोई थोड़ा हल्का छोड़ सकता है? धन्यवाद।दो सूची की तुलना करें <int>

 List<int> groupA = new List<int>(); 
     List<int> groupB = new List<int>(); 

     List<int> dups = new List<int>(); 
     List<int> distinct = new List<int>(); 

     groupA.Add(2); 
     groupA.Add(24); 
     groupA.Add(5); 
     groupA.Add(72); 
     groupA.Add(276); 
     groupA.Add(42); 
     groupA.Add(92); 
     groupA.Add(95); 
     groupA.Add(266); 
     groupA.Add(42); 
     groupA.Add(92); 


     groupB.Add(5); 
     groupB.Add(42); 
     groupB.Add(95); 

     groupA.Sort(); 
     groupB.Sort(); 

     for (int a = 0; a < groupA.Count; a++) 
     { 
      for (int b = 0; b < groupB.Count; b++) 
      { 
       groupA[a].CompareTo(groupB[b]); 


       if (groupA[a] == groupB[b]) 
       { 
        dups.Add(groupA[a]); 
        groupA.Remove(groupA[a]); 
        groupB.Remove(groupB[b]); 
       } 

      } 
      distinct.Add(groupA[a]); 
     } 
+0

क्या आप अपेक्षित परिणाम पोस्ट कर सकते हैं? –

+0

मुझे लगता है कि आप जल्द ही समूह [बी] को हटा रहे हैं। क्योंकि यह आपके ए 1 -> बी 1 2 3 4 5 6 7 आदि, ए 2 -> बी 1 2 3 4 5 जैसे कार्यों के लिए है।यदि आप बी से कोई संख्या हटाते हैं, तो यह डुप्लिकेट या विशिष्ट में दिखाई नहीं दे पाएगा। लेकिन यह सिर्फ मेरी वृत्ति है। :) –

+0

आप उन्हें पुनरावृत्त करते समय सूचियों से तत्वों को हटा रहे हैं, इसलिए लूप स्थितियों (तत्व संख्याओं के आधार पर) समझौता किया जा सकता है ... – digEmAll

उत्तर

34

मैं Intersect और Except तरीकों का प्रयोग करेंगे कर सकता है (मानते हुए कि मैं सही ढंग से समझ रहा था कि आप क्या करने का प्रयास कर रहे थे)

+1

उपरोक्त, अच्छा और आसान समाधान। – PawelCz

+0

सूची की लंबाई महत्वपूर्ण है। var l1 = नई सूची () {1, 5, 6}; var l2 = नई सूची () {6, 5, 1, 2}; l2.Except (l1) => 2. l1.Except (l2) => कुछ भी नहीं –

8

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

उदाहरण के लिए, निम्नलिखित कोड गलत

List<int> nums = new List<int>{2, 4, 6, 7, 8, 10, 11}; 

for (int i = 0; i < nums.Count; i++) 
{ 
    if (nums[i] % 2 == 0) 
    nums.Remove(nums[i]); 
} 

है, तो बस {7, 11} के बजाय सूची {4, 7, 10, 11} वापस आ जाएगी।

यह 4 के मान को नहीं निकाला जाएगा, क्योंकि जब मैं 2 का मूल्य, (i=0 के लिए) को हटाने nums सूची

//index 0 1 2 3 4 5 6 
nums = {2, 4, 6, 7, 8, 10, 11} 

से

//index 0 1 2 3 4 5 
nums = {4, 6, 7, 8, 10, 11} 

पाश खत्म को जाता है , मुझे 1 तक बढ़ाया गया है, और अगला आइटम संदर्भित किया गया है nums[1], जो कि 4 की अपेक्षा नहीं करता है, लेकिन 6 की कीमत कम हो जाती है, और चेक को निष्पादित नहीं किया जाता है।

आपको हर बार बहुत सावधान रहना चाहिए जब आप उस संग्रह को संशोधित कर रहे हों जिसे आप पुन: सक्रिय कर रहे हैं। उदाहरण के लिए, foreach कथन एक अपवाद फेंक देगा यदि आप इसे भी आजमाते हैं। इस मामले में आप भी,, के लिए कांटा सकता है की तरह

for (int i = 0; i < nums.Count; i++) 
{ 
    if (nums[i] % 2 == 0) 
    { 
    nums.Remove(nums[i]); 
    i--; //decrement the counter, so that it will stay in place 
     //when it is incremented at the end of the loop 
    } 
} 

इस तरह वैकल्पिक रूप से आप LINQ इस्तेमाल कर सकते हैं जैसे

List<int> nums = new List<int>{2, 4, 6, 7, 8, 10, 11}; 

int i = 0; 
while (i < nums.Count) 
{ 
    if (nums[i] % 2 == 0) 
    { 
    nums.Remove(nums[i]) 
    }  
    else 
    { 
    i++; //only increment if you are not removing an item 
     //otherwise re-run the loop for the same value of i 
    } 
} 
आप की

थोड़ी देर के इस्तेमाल कर सकते हैं:

distinct.AddRange(groupA); 
distinct.AddRange(groupB); 
distinct = distinct.Distinct().ToList(); 

और

dups.AddRange(groupA); 
dups.AddRange(groupB); 

dups = dups.GroupBy(i => i) 
      .Where(g => g.Count() > 1) 
      .Select(g => g.Key) 
      .ToList(); 

ध्यान दें कि LINQ कोड आपके मौजूदा समूह ए और ग्रुपबी सूचियों को नहीं बदलेगा।

dups = groupA.Intersect(groupB).ToList(); 
distinct = groupA.Except(groupB).ToList(); 
+0

थोड़ी देर के साथ लूप के लिए दोनों को बदलें? – jpavlov

+0

मैं आपके कार्यान्वयन को आपके पास छोड़ दूंगा, लेकिन मैंने एक उदाहरण जोड़ा है जो दिखाता है कि आपका कोड कहां गलत है, और इसे कैसे ठीक किया जाए। – SWeko

4

आप Linq के साथ यह आसानी से कर सकते हैं::

List<int> dups = groupA.Intersect(groupB).ToList(); 
    List<int> distinct = groupA.Except(groupB).ToList(); 

आप सिर्फ उन्हें अलग करना चाहते हैं, तो आप सिर्फ

groupA = groupA.Distinct().ToList(); 
groupB = groupB.Distinct().ToList(); 
संबंधित मुद्दे