2013-01-08 48 views
10

İki Liste'yi karşılaştırmak için küçük bir program yazıyorum. Değerler aynıysa, bunları liste kopyalarına eklerim, eğer farklılarsa, onları ayrı olarak eklerim. Bazı değerlerimin eklendiğini ve bazılarının olmadığını ve bir süre hata ayıkladıktan sonra sorunun ne olduğundan emin olmadığımı fark ettim. Birisi biraz ışık tutabilir mi? Teşekkürler.İkili Karşılaştır <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

Beklenen sonuçları kaydeder misiniz? –

+0

Sanırım [b] grubunu yakında kaldırıyorsunuz. Çünkü sizin için bu A1 -> B 1 2 3 4 5 6 7 vs gibi işler, A2 -> b1 2 3 4 5.Bir sayıyı b'den kaldırırsanız, dups veya ayrı olarak gösterilemez. Ama bu sadece içgüdüm. :) –

+0

Onları yineleyerek öğeleri listeden çıkarıyorsunuz, böylece döngü koşulları (öğe sayısına göre) tehlikeye düşebilir ... – digEmAll

cevap

34

Ben Intersect ve Except yöntemlerini kullanmak yapabilirdi (Ne yapmaya çalıştığımı doğru bir şekilde anladığımı varsayarak)

+1

Giden, güzel ve kolay bir çözüm. – PawelCz

+0

Listenin uzunluğu önemlidir. var l1 = yeni Liste () {1, 5, 6}; var l2 = yeni Liste () {6, 5, 1, 2}; l2.Except (l1) => 2. l1.Except (l2) => hiçbir şey –

8

Listeden bir öğeyi kaldırdığınızda, kalan öğenin dizinini aşağı taşırsınız. Özünde, bazı öğeleri bir for döngüsü kullanarak atlıyorsunuz.
Bir süre döngü kullanmayı deneyin ve bir öğeyi silmediğinizde sayacı manuel olarak artırın. Sadece {7, 11} yerine listesini {4, 7, 10, 11} dönecektir Eğer

Örneğin, aşağıdaki kod

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]); 
} 

yanlıştır.

I ( i=0 için), 2 değerini çıkarmak zaman, çünkü nums listesi

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

Döngü tamamlandığında için

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

gider, 4 değerine kaldırılmayacak

i, 1'e artırılır ve başvurulan bir sonraki öğe nums[1]'dur; bu, sezgisel olarak beklendiği gibi 4 değildir, ancak 6. Yani, 4 değeri atlanır ve kontrol gerçekleştirilmez.

Yinelediğiniz koleksiyonu değiştirdiğinizde her zaman çok dikkatli olmalısınız. Örneğin, bunu denerseniz foreach ifadesi bir istisna atar. Bu durumda, böyle bile Alternatif linq kullanabilirsiniz

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 
    } 
} 

sanki, çatal olabilir sizin

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 
    } 
} 

gibi bir süre kullanabilirsiniz:

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

ve

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

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

Not LINQ kod, mevcut groupA ve groupB listelerinizi değiştirmeyecektir.

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

Döngüleri bir süre döngü ile değiştirir misiniz? – jpavlov

+0

Uygulamanızı size bırakacağım, ancak kodunuzun yanlış gittiğini ve nasıl düzeltileceğini gösteren bir örnek ekledim. – SWeko

4

Sen Linq ile bunu kolayca yapabilirsiniz:

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

sadece onları farklı istiyorsanız, sadece

groupA = groupA.Distinct().ToList(); 
groupB = groupB.Distinct().ToList(); 
İlgili konular